Go语言中的条件语句(if)的作用域问题

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

Go scope with conditional statements (if) issue

问题

我是你的中文翻译助手,以下是翻译好的内容:

我刚开始学习Go语言,对于作用域(如其他人所提到的)感到困惑。

下面的代码会生成以下错误信息:

./excel.go:24: err declared and not used
./excel.go:25: sheet declared and not used

为什么会出现这个错误?我在父作用域中声明了errsheet变量,不是吗?

Excel.go:

package main

import (
	"os"
    "fmt"
    "github.com/tealeg/xlsx"
)

func main() {
    var file *xlsx.File
    var sheet *xlsx.Sheet
    var row *xlsx.Row
    var cell *xlsx.Cell
    var err error

	fileName := "MyXLSXFile.xlsx"
	
    if _, err := os.Stat(fileName); os.IsNotExist(err) {
    	fmt.Printf("文件不存在,创建一个")
		file = xlsx.NewFile()
    	sheet, err = file.AddSheet("Sheet1")
	} else {
		fmt.Printf("文件存在,打开它")
		file, err := xlsx.OpenFile(fileName) // <-- 第24行
    	sheet := file.Sheets[0] // <-- 第25行
	}

    row = sheet.AddRow()

    cell = row.AddCell()
    cell.Value = "我是一个单元格!"
    cell = row.AddCell()
    cell.Value = "我是另一个单元格!"

    err = file.Save(fileName)

    if err != nil {
        fmt.Printf("帮助")
    }
}
英文:

I'm new to Go and I'm struggling with scope (as others).

The code below generates:

./excel.go:24: err declared and not used
./excel.go:25: sheet declared and not used

Why does this happen? I have declared both err and sheet in the parent scope, haven't I?

Excel.go:

package main

import (
	&quot;os&quot;
    &quot;fmt&quot;
    &quot;github.com/tealeg/xlsx&quot;
)

func main() {
    var file *xlsx.File
    var sheet *xlsx.Sheet
    var row *xlsx.Row
    var cell *xlsx.Cell
    var err error

	fileName := &quot;MyXLSXFile.xlsx&quot;
	
    if _, err := os.Stat(fileName); os.IsNotExist(err) {
    	fmt.Printf(&quot;File does not exist so create one&quot;);
		file = xlsx.NewFile()
    	sheet, err = file.AddSheet(&quot;Sheet1&quot;)
	} else {
		fmt.Printf(&quot;File exists so open&quot;);
		file, err := xlsx.OpenFile(fileName) // &lt;-- line 24
    	sheet := file.Sheets[0] // &lt;-- line 25
	}

    row = sheet.AddRow()

    cell = row.AddCell()
    cell.Value = &quot;I am a cell!&quot;
    cell = row.AddCell()
    cell.Value = &quot;I am another cell!&quot;

    err = file.Save(fileName)

    if err != nil {
        fmt.Printf(&quot;help&quot;)
    }
}

答案1

得分: 2

使用=代替:=

    file, err = xlsx.OpenFile(fileName) // &lt;-- 第24行
    sheet = file.Sheets[0] // &lt;-- 第25行

Go语言允许在嵌套块中重新声明同名变量。:=声明一个新变量。在你的情况下,errsheet都在else块内声明,但在那里没有使用。

英文:

Use = instead of :=:

    file, err = xlsx.OpenFile(fileName) // &lt;-- line 24
    sheet = file.Sheets[0] // &lt;-- line 25

Go allows re-declaring variables with the same name in nested blocks. := declares a new variable. In your case both err and sheet are declared inside else block but are not used there.

答案2

得分: 2

TL;DR:使用=进行纯赋值。:=声明一个新变量。

sheet := file.Sheets[0]else块的作用域内声明了一个新变量(参见语言规范中的“短变量声明”章节)。这个变量遮蔽了外部作用域中同名的变量,并且不会存在于外部作用域中(参见文档):

在函数内部声明的常量或变量标识符的作用域从ConstSpec或VarSpec(对于短变量声明为ShortVarDecl)的结束开始,并在最内层包含块的结束处结束。

因此,第25行的变量sheet和第12行和第28行的变量sheet实际上是两个不同的变量(第一个在赋值后从未被使用)。

英文:

TL;DR: Use = for pure assignments. := declares a new variable.

sheet := file.Sheets[0] declares a new variable within the scope of the else block (see the chapter "Short variable declaration" from the language spec). This variable shadows the variable of the same name declared in the outer scope and will not exist in the outer scope (see the documentation):

>The scope of a constant or variable identifier declared inside a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl for short variable declarations) and ends at the end of the innermost containing block.

So the variable sheet in line 25 and the variable sheet in lines 12 and 28 are actually two different variables (with the first one declared in line 25 never being used after assignment).

huangapple
  • 本文由 发表于 2016年1月6日 20:47:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/34633547.html
匿名

发表评论

匿名网友

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

确定