英文:
go compile errors: undefined variables
问题
package main
import (
"fmt"
"io"
"os"
)
const file = "readfile.txt"
var s string
func lookup(string) (string, string, string) {
artist := s
album := s
year := s
return artist, album, year
}
func enterdisk() (string, string, string) {
var artist string
var album string
var year string
println("enter artist:")
fmt.Scanf("%s", &artist)
println("enter album:")
fmt.Scanf("%s", &album)
println("enter year:")
fmt.Scanf("%s", &year)
return artist, album, year
}
func main() {
println("enter UPC or [manual] to enter information manually:")
fmt.Scanf("%s", &s)
s := s
switch s {
case "manual\n": artist, album, year := enterdisk()
default: artist, album, year := lookup(s)
}
f,_ := os.OpenFile(file, os.O_APPEND|os.O_RDWR, 0666)
io.WriteString(f, (artist + ", \"" + album + "\" - " + year + "\n"))
f.Close()
println("wrote data to file")
}
英文:
new to programming / even newer to go. having trouble with a small go program - will not compile with undefined variable errors. the code:
package main
import (
"fmt"
"io"
"os"
)
const file = "readfile.txt"
var s string
func lookup(string) (string, string, string) {
artist := s
album := s
year := s
return artist, album, year
}
func enterdisk() (string, string, string) {
var artist string
var album string
var year string
println("enter artist:")
fmt.Scanf("%s", &artist)
println("enter album:")
fmt.Scanf("%s", &album)
println("enter year:")
fmt.Scanf("%s", &year)
return artist, album, year
}
func main() {
println("enter UPC or [manual] to enter information manually:")
fmt.Scanf("%s", &s)
s := s
switch s {
case "manual\n": artist, album, year := enterdisk()
default: artist, album, year := lookup(s)
}
f,_ := os.OpenFile(file, os.O_APPEND|os.O_RDWR, 0666)
io.WriteString(f, (artist + ", \"" + album + "\" - " + year + "\n"))
f.Close()
println("wrote data to file")
}
and the errors:
catalog.go:49: undefined: artist
catalog.go:49: undefined: album
catalog.go:49: undefined: year
however, those variables will not be defined until the code runs. additionally, the "lookup" function is not yet written, which it just returns what it is passed. i know the lookup and enterdisk functions work on their own, but i am trying to test the switch statement.
i have tried declaring the variables in main, however i get this error:
catalog.go:49: artist declared and not used
catalog.go:49: album declared and not used
catalog.go:49: year declared and not used
p.s. i have read http://tip.goneat.org/doc/go_faq.html#unused_variables_and_imports , and i agree that if this is only semantics, i still want to fix it. i just don't know how!
答案1
得分: 5
阅读关于Go中的blocks和declarations and scope的内容。
在switch或select语句中的每个子句都充当隐式块。
块可以嵌套并影响作用域。
声明的标识符的作用域是源代码中标识符指定的常量、类型、变量、函数或包的范围。
在函数内部声明的常量或变量标识符的作用域从ConstSpec或VarSpec(对于短变量声明为ShortVarDecl)的结束开始,并在最内层包含块的结束处结束。
switch s {
case "manual\n": artist, album, year := enterdisk()
default: artist, album, year := lookup(s)
}
. . .
io.WriteString(f, (artist + ", \"" + album + "\" - " + year + "\n"))
在switch
的case
和default
子句中,artist
、album
和year
变量的短变量声明的作用域在每个子句内部(最内层包含块)开始和结束。artist
、album
和year
变量不再存在,并且对WriteString()
语句不可见。
改为:
var artist, album, year string
switch s {
case "manual\n":
artist, album, year = enterdisk()
default:
artist, album, year = lookup(s)
}
. . .
io.WriteString(f, (artist + ", \"" + album + "\" - " + year + "\n"))
与常规变量声明不同,短变量声明可以重新声明变量,前提是它们最初在同一块中以相同的类型声明,并且至少有一个非空白变量是新的。因此,重新声明只能出现在多变量的短声明中。
因此,在switch case子句中不再使用短变量声明来声明(和赋值)artist
、album
和year
变量,因为这会隐藏外部块中的变量声明,它们只是被赋值。
英文:
Read about blocks and declarations and scope in Go.
> Each clause in a switch or select statement acts as an implicit block.
>
> Blocks nest and influence scoping.
>
> The scope of a declared identifier is the extent of source text in
> which the identifier denotes the specified constant, type, variable,
> function, or package.
>
> 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.
switch s {
case "manual\n": artist, album, year := enterdisk()
default: artist, album, year := lookup(s)
}
. . .
io.WriteString(f, (artist + ", \"" + album + "\" - " + year + "\n"))
The scope of the short variable declarations of the artist
, album
, and year
variables in the switch
case
and default
case clauses begins and ends within each clause (the innermost containing block). The artist
, album
, and year
variables no longer exist and are not visible to the WriteString()
statement.
Instead, write:
var artist, album, year string
switch s {
case "manual\n":
artist, album, year = enterdisk()
default:
artist, album, year = lookup(s)
}
. . .
io.WriteString(f, (artist + ", \"" + album + "\" - " + year + "\n"))
> Unlike regular variable declarations, a short variable declaration may
> redeclare variables provided they were originally declared in the same
> block with the same type, and at least one of the non-blank variables
> is new. As a consequence, redeclaration can only appear in a
> multi-variable short declaration.
Therefore, the artist
, album
, and year
variables are no longer declared (and assigned) using short variable declarations inside the switch case clauses because that would hide the variable declarations in the outer block, they are merely assigned.
答案2
得分: 3
当您有变量被有条件地赋值时,您必须在条件之前声明它们。所以,不要这样写:
switch s {
case "manual\n": artist, album, year := enterdisk()
default: artist, album, year := lookup(s)
}
...试试这样写:
var artist, album, year string
switch s {
case "manual\n": artist, album, year = enterdisk()
default: artist, album, year = lookup(s)
}
(即使您设置了一个默认值,编译器也不喜欢它们没有先声明。或者也许它不喜欢它们在每个条件中都声明了两次,我不确定)
您看,现在我们首先声明了变量,在switch条件内设置了它们的值。一般规则是:如果您要在if/switch/for之外使用变量,请先声明它们,以便在将要使用的范围内访问它们。
英文:
When you have variables being assigned conditionally, you must declare them before the conditions. So instead of:
switch s {
case "manual\n": artist, album, year := enterdisk()
default: artist, album, year := lookup(s)
}
...try this:
var artist, album, year string
switch s {
case "manual\n": artist, album, year = enterdisk()
default: artist, album, year = lookup(s)
}
(even though you have set a default, the compiler doesn't like that they are not declared first. Or maybe it doesn't like that they are declared twice, one in each condition, I'm not sure)
You see, now first we declare the variables, and inside the switch condition their values are set. The general rule is: if you are going to use the variables outside of the if/switch/for, declare them first to make them accessible in the scope they will be used.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论