新编程/甚至更新。使用小型程序时遇到问题 - 不会使用未定义的变量错误进行编译。代码:
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")
}
和错误:
catalog.go:49: undefined: artist
catalog.go:49: undefined: album
catalog.go:49: undefined: year
但是,在代码运行之前,不会定义这些变量。另外,“查找”功能尚未写入,它只返回传递的内容。我知道查找和enterdisk函数自己工作,但我试图测试switch语句。
我试过在main中声明变量,但是我得到了这个错误:
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。我已阅读http://tip.goneat.org/doc/go_faq.html#unused_variables_and_imports,我同意如果这只是语义,我仍然想解决它。我只是不知道怎么做!
答案 0 :(得分:4)
在blocks中了解declarations and scope和Go。
switch或select语句中的每个子句都充当隐式块。
阻止嵌套并影响范围。
声明的标识符的范围是源文本的范围 其中标识符表示指定的常量,类型,变量, 功能或包装。
在a中声明的常量或变量标识符的范围 函数从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"))
artist
album
和year
中switch
,case
和default
个变量的short variable declarations范围case子句在每个子句(最里面的包含块)内开始和结束。 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"))
与常规变量声明不同,短变量声明可以 重新声明变量,只要它们最初在同一声明中声明 具有相同类型的块,以及至少一个非空白变量 是新的。因此,重新声明只能出现在 多变量简短声明。
因此,在{case}子句中使用short variable declarations不再声明(和分配)artist
,album
和year
变量,因为这会隐藏变量在外部区块中的声明,它们仅被分配。
答案 1 :(得分:2)
如果有条件地分配变量,则必须在条件之前声明它们。所以而不是:
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)
}
(即使你设置了一个默认值,编译器也不喜欢它们没有被声明为第一个。或者它可能不喜欢它们被声明两次,每个条件一个,我不确定)< / p>
你看,现在我们首先声明变量,并在switch条件中设置它们的值。一般规则是:如果要使用if / switch / for之外的变量,首先声明它们以便在范围内访问它们。