分享到:文章主题: 请教两个Go的新手问题
raaay0608楼主
raaay0608
等级
用户
文章
329
积分
5869
星座
双子座
发信人: raaay0608 (raaay0608), 信区: Golang
标  题: 请教两个Go的新手问题
发信站: 北邮人论坛 (Tue May 15 11:54:46 2018), 站内

首先第一个是defer和err处理的顺序问题,应该先做哪一步的问题,比如如下两种写法

```go
func f1() {
    f, err := os.Open("/file.txt")
    if (err != nil) {
        return
    }
    defer f.Close()
}

func f2() {
    f, err := os.Open("/file.txt")
    defer f.Close()
    if (err != nil) {
        return
    }
}
```

哪一种应该算是正确的呢?

第二个问题是,Go垃圾回收也会回收指针,比如`f, _ := os.Open("file.txt")`后,如果没有调用`f.Close()`,垃圾回收的时候Runtime会做“善后”工作吗?



--

※ 来源:·北邮人论坛 http://bbs.byr.cn·[FROM: 2001:da8:215:c5e7:48af:14dc:c87d:*]
    返回顶部
    cc19931002沙发
    啦啦
    等级
    用户
    文章
    326
    积分
    5745
    星座
    天秤座
    发信人: cc19931002 (啦啦), 信区: Golang
    标  题: Re: 请教两个Go的新手问题
    发信站: 北邮人论坛 (Tue May 15 13:53:14 2018), 站内

    感觉第二种比较好
    --

    ※ 来源:·北邮人论坛 http://bbs.byr.cn·[FROM: 10.108.216.*]
      返回顶部
      lsp板凳
      doombaba
      等级
      用户
      文章
      1747
      积分
      16602
      星座
      双鱼座
      发信人: lsp (doombaba), 信区: Golang
      标  题: Re: 请教两个Go的新手问题
      发信站: 北邮人论坛 (Wed May 16 13:16:33 2018), 站内

      第一种比较好;不会
      --

      ※ 来源:·北邮人论坛 http://bbs.byr.cn·[FROM: 111.204.243.*]
        返回顶部
        lzj0218第3楼
        Snail
        等级
        用户
        文章
        439
        积分
        10302
        星座
        水瓶座
        发信人: lzj0218 (Snail), 信区: Golang
        标  题: Re: 请教两个Go的新手问题
        发信站: 北邮人论坛 (Wed May 16 20:43:25 2018), 站内

        第一个问题,《The Go Programming Language》中建议在打开资源后立即使用`defer`写好关闭资源的操作
        而且第一种写法实际上是错误的,在`err != nil`时,`defer`后面的`f.Close()`函数不会执行到
        楼主可以运行一下下面这段代码就看得出来了
        
        ```Go
        package main
        
        import "os"
        import "fmt"
        
        func f1() {
            _, err := os.Open("/file.txt")
            if (err != nil) {
                return
            }
            defer func() {
                fmt.Println("f1: hello world!")
            }()
        }
        
        func f2() {
            _, err := os.Open("/file.txt")
            defer func() {
                fmt.Println("f2: hello world!")
            }()
            if (err != nil) {
                return
            }
        }
        
        func main() {
            f1()
            f2()
        }
        ```
        
        第二个问题,垃圾回收的时候应该都不会做关闭资源这些操作吧,Go具体怎么做的不是很清楚

        --
        ※ 修改:·lzj0218 于 May 16 20:45:03 2018 修改本文·[FROM: 120.52.147.*]
        ※ 来源:·北邮人论坛 http://bbs.byr.cn·[FROM: 120.52.147.*]
          返回顶部
          lsp第4楼
          doombaba
          等级
          用户
          文章
          1747
          积分
          16602
          星座
          双鱼座
          发信人: lsp (doombaba), 信区: Golang
          标  题: Re: 请教两个Go的新手问题
          发信站: 北邮人论坛 (Sat May 19 23:24:52 2018), 站内


          【 在 lzj0218 的大作中提到: 】
          : [md]
          : 第一个问题,《The Go Programming Language》中建议在打开资源后立即使用`defer`写好关闭资源的操作
          : 而且第一种写法实际上是错误的,在`err != nil`时,`defer`后面的`f.Close()`函数不会执行到
          : ...................

          err !=nil时,defer后面的还有执行的必要么。就是那个f.Close()
          --

          ※ 来源:·北邮人论坛 http://bbs.byr.cn·[FROM: 124.127.222.*]
            返回顶部
            lzj0218第5楼
            Snail
            等级
            用户
            文章
            439
            积分
            10302
            星座
            水瓶座
            发信人: lzj0218 (Snail), 信区: Golang
            标  题: Re: 请教两个Go的新手问题
            发信站: 北邮人论坛 (Sun May 20 12:42:24 2018), 站内

            em......确实,Open的时候出错的话返回的f是个nil,那没有执行f.Close()的必要了

            【 在 lsp 的大作中提到: 】
            :  
            : err !=nil时,defer后面的还有执行的必要么。就是那个f.Close()

            --

            ※ 来源:·北邮人论坛 http://bbs.byr.cn·[FROM: 120.52.147.*]
              返回顶部
              lizz第6楼
              シャノちゃん
              等级
              用户
              文章
              495
              积分
              26167
              发信人: lizz (シャノちゃん), 信区: Golang
              标  题: Re: 请教两个Go的新手问题
              发信站: 北邮人论坛 (Sun May 20 18:34:50 2018), 站内

              第一个问题,肯定是用f1

              Go里的结构体函数其实是语法糖,所以f.Close()相当于C里的fclose(f)。
              当os.Open()返回error时,f的值为nil,所以实际调用了flose(nil)。
              很多情况下,对nil进行对象操作是undefined behavior,任何后果都有可能发生。
              Go对fclose做了零值判断以避免崩溃,参见 https://golang.org/src/os/file_unix.go?s=5771:5799#L189

              如果你写过C,就会知道资源申请失败是不能进行释放操作,否则分分钟segmentation fault。


              第二个问题,Go不支持自动RAII,指针释放时不会有所谓的析构操作,所以不释放资源的话会造成fd泄露。
              如果想使用RAII的写法可以换一门语言,比如C++或Rust。





              --
              ※ 修改:·lizz 于 May 20 18:35:40 2018 修改本文·[FROM: 123.123.254.*]
              ※ 来源:·北邮人论坛 http://bbs.byr.cn·[FROM: 123.123.254.*]
                返回顶部
                Muggins第7楼
                莫泽
                等级
                用户
                文章
                61
                积分
                7703
                星座
                金牛座
                发信人: Muggins (莫泽), 信区: Golang
                标  题: Re: 请教两个Go的新手问题
                发信站: 北邮人论坛 (Fri May 25 16:06:33 2018), 站内

                第一个问题肯定用f2,至于楼上说的如果open失败,file为nil,close(nil)在golang中也是保护的,f.close()函数会返回error作为提示;
                第二个问题,golang触发垃圾回收机制时,当object被回收时文件会自动关闭,这个也是golang基本的保护,不然坑就太大了。
                --

                ※ 来源:·北邮人论坛 http://bbs.byr.cn·[FROM: 120.52.147.*]
                  返回顶部
                  • 文章数:8 分页:
                    1. 1