去编译错误:未定义的变量

ric*_*ick 4 variables go

编程新手,甚至更新。使用小型go程序遇到麻烦-无法编译未定义的变量错误。代码:

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")
}
Run Code Online (Sandbox Code Playgroud)

和错误:

catalog.go:49: undefined: artist
catalog.go:49: undefined: album
catalog.go:49: undefined: year
Run Code Online (Sandbox Code Playgroud)

但是,在代码运行之前,将不会定义这些变量。此外,“ lookup”功能尚未编写,它只是返回传递的内容。我知道lookup和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
Run Code Online (Sandbox Code Playgroud)

附言:我已经阅读了http://tip.goneat.org/doc/go_faq.html#unused_variables_and_imports,并且我同意如果这仅仅是语义,我仍然想对其进行修复。我只是不知道如何!

pet*_*rSO 5

Go中阅读有关声明以及范围的信息。

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")) 
Run Code Online (Sandbox Code Playgroud)

所述的范围短变量声明的的artistalbum以及year在各变量switch casedefault壳体子句的开始和结束的每个条款(含最内块)内。的artistalbumyear变量不再存在,并且不可见的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"))
Run Code Online (Sandbox Code Playgroud)

与常规变量声明不同,短变量声明可以重新声明变量,前提是它们最初是在同一块中以相同类型声明的,并且至少一个非空白变量是新变量。因此,重新声明只能出现在多变量简短声明中。

因此,artistalbum,和year变量使用不再声明(和分配的)短的变量声明在开关壳体内部的条款,因为这将隐藏在外部块的变量声明,它们仅仅分配。