1

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 ( "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 does not exist so create one"); file = xlsx.NewFile() sheet, err = file.AddSheet("Sheet1") } else { fmt.Printf("File exists so open"); file, err := xlsx.OpenFile(fileName) // <-- line 24 sheet := file.Sheets[0] // <-- line 25 } row = sheet.AddRow() cell = row.AddCell() cell.Value = "I am a cell!" cell = row.AddCell() cell.Value = "I am another cell!" err = file.Save(fileName) if err != nil { fmt.Printf("help") } } 

2 Answers 2

3

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).

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the link, I misunderstood the = and := principle.
2

Use = instead of :=:

 file, err = xlsx.OpenFile(fileName) // <-- line 24 sheet = file.Sheets[0] // <-- 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.

1 Comment

Note that both file and err need to declared beforehand to use = in the if statement. If you declare file before the if and expect if file, err := someFunc() to use the file you declared before, it won't work (you'll get file declared but not used error) and if you do if file, err = someFunc() that won't work either because err is not defined.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.