:= operator and if statement in Golang

huangapple go评论89阅读模式
英文:

:= operator and if statement in Golang

问题

以下是翻译好的内容:

以下是一个打开文件的函数:

func openFile(filename string) {
  var file *os.File
  var err error
  if file, err = os.Open(filename); err != nil {
    log.Printf("无法打开文件:%s。", filename)
    return
  }
  defer file.Close()
  // 其他操作
}

然而,当我尝试使用:=来声明变量file时,它不起作用:

func updateFrequencies(filename string, frequencyForWord map[string]int) {
  if file, err := os.Open(filename); err != nil {
     // ...
  }
}

错误信息:./word_frequencies_2.go:30: undefined: file

但是,如果我稍微修改一下,它就可以工作了:

file, err := os.Open(filename)
if err != nil {
   log.Printf("无法打开文件:%s。", filename)
   return
}

为什么我不能在if语句中使用:=呢?

英文:

The following works as a function to open a file

func openFile(filename string) {
  var file *os.File
  var err error
  if file, err = os.Open(filename); err != nil {
    log.Printf("Failed to open the file: %s.", filename)
    return
  }
  defer file.Close()
  // blahblahblah
}

however, this does not work, when I try to use := to declare the variable file

func updateFrequencies(filename string, frequencyForWord map[string]int) {
  if file, err := os.Open(filename); err != nil {
     ....
  }
}

error: ./word_frequencies_2.go:30: undefined: file

But if I changed this slightly, this works

file, err := os.Open(filename)
if err != nil {
   log.Printf("Failed to open the file: %s.", filename)
   return
}

why can't I use := as part of the if statement?

答案1

得分: 44

为什么我不能在if语句中使用:=?

你可以使用,但是变量的作用域仅限于if代码块内部。所以,在if代码块之外,file变量是未定义的。

同样的规则也适用于for循环、switch语句和类似的代码块。

英文:

> Why can't I use := as part of the if statement?

You can, but then the variables are defined within the scope of the if block. So, file is not defined outside of your if block.

The same rule applies to definitions in for, switch, and similar blocks.

答案2

得分: 7

Mostafa已经指出file变量在if块之外没有定义,你已经看到了如何修复这个问题。

但是你的函数还有两个更重要的问题。

第一个问题是它没有返回任何东西。

你可以通过将其更改为以下形式来修复:

func openFile(filename string) (*os.File, error) {
     ... 实现
     return file, nil
}

但这会引发另一个问题:当函数结束时,由于defer file.Close(),它会关闭文件,因此该函数的用户会收到一个已关闭的文件。事实上,你的函数并没有真正意义。你可以通过让它传递一个回调函数来使用文件,或者让用户关闭文件来修复它,但正确的做法是在需要时直接打开文件。

英文:

Mostafa already pointed that the file variable isn't defined out of the if block and you already saw how to fix that.

But your function has two more important problems.

The first one is that it doesn't return anything.

You could fix that by changing it to

func openFile(filename string) *os.File, error {
     ... implementation
     return file, nil
}

But that would let another one : when your function ends, it closes the file because of defer file.Close() so that the user of this function receives a closed file. The truth is that your function doesn't make really sense. You could fix it by letting it pass a callback that would use the file, or by letting the user close the file, but the right thing to do is to directly open the file where you need it.

huangapple
  • 本文由 发表于 2013年9月9日 20:15:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/18698011.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定