加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

[日常] Go语言圣经-Deferred函数

发布时间:2020-12-16 19:36:14 所属栏目:大数据 来源:网络整理
导读:1.只需要在调用普通函数或方法前加上关键字defer,就完成了defer所需要的语法。当defer语句被执行时,跟在defer后面的函数会被延迟执行。直到包含该defer语句的函数执行完毕时,defer后的函数才会被执行,不论包含defer语句的函数是通过return正常结束,还是

1.只需要在调用普通函数或方法前加上关键字defer,就完成了defer所需要的语法。当defer语句被执行时,跟在defer后面的函数会被延迟执行。直到包含该defer语句的函数执行完毕时,defer后的函数才会被执行,不论包含defer语句的函数是通过return正常结束,还是由于panic导致的异常结束

2.defer语句经常被用于处理成对的操作,如打开、关闭、连接、断开连接、加锁、释放锁。通过defer机制,不论函数逻辑多复杂,都能保证在任何执行路径下,资源被释放。释放资源的defer应该直接跟在请求资源的语句后

3.defer语句会先调用,defer后面的函数会最后调用,两层函数,配合返回匿名函数函数值实现trace功能defer trace("bigSlowOperation")()

4.http响应写入文件 n,err = io.Copy(f,resp.Body)

练习5.18:不修改fetch的行为,重写fetch函数,要求使用defer机制关闭文件。

//导入io/ioutil和net/http包
import (
"fmt"
"io"
"os"
//"io/ioutil"
"net/http"
"strings"
//"time"
"net/url"
)
/
练习5.18:不修改fetch的行为,重写fetch函数,要求使用defer机制关闭文件。
/
func main() {
//开始时间
//start := time.Now()
//for循环命令行参数
for _,u := range os.Args[1:] {
//加入前缀
if !strings.HasPrefix(u,"http://") {
u = "http://" + u
}
res,err := http.Get(u)
//判断错误
if err != nil {
//向标准错误流打印信息
fmt.Fprintf(os.Stderr,"fetch:%v n",err)
//终止进程
os.Exit(1)
}
//使用defer机制
defer res.Body.Close()

            urlObj,_ := url.Parse(u)
            filename := urlObj.Path
            if filename == "/" {
                    filename = "index.html"
            }   
            var f *os.File
            f,err = os.Create(filename)
            //使用defer机制
            /*  
            我们没有对f.close采用defer机制,因为这会产生一些微妙的错误。许多文件系统,尤其是NFS,写入文件时发生的错误会被延迟到文件关闭时反馈。如果没有检查文件关闭时的反馈信息,可能会导致数

据丢失,而我们还误以为写入操作成功。如果io.Copy和f.close都失败了,我们倾向于将io.Copy的错误信息反馈给调用者,因为它先于f.close发生,更有可能接近问题的本质。
*/
defer f.Close()
_,res.Body)
//判断错误
if err != nil {
//向标准错误流打印信息
fmt.Fprintf(os.Stderr,err)
//终止进程
os.Exit(1)
}
}
}

  

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读