我遇到了一个奇怪的问题,下面的代码无法编译:
func main() {
var val reflect.Value
var tm time.Time
if tm, err := time.Parse(time.RFC3339, "2018-09-11T17:50:54.247Z"); err != nil {
panic(err)
}
val = reflect.ValueOf(tm)
fmt.Println(val, tm, reflect.TypeOf(tm))
}
Run Code Online (Sandbox Code Playgroud)
有错误(代码是linter推荐的):
$ go run main.go
# command-line-arguments
./main.go:13:5: tm declared and not used
Run Code Online (Sandbox Code Playgroud)
注意tm确实使用了变量.
但是,如果我添加一个else块 - 一切都按预期编译:
func main() {
var val reflect.Value
var tm time.Time
if tm, err := time.Parse(time.RFC3339, "2018-09-11T17:50:54.247Z"); err != nil {
panic(err)
} else {
val = reflect.ValueOf(tm)
}
fmt.Println(val, tm, reflect.TypeOf(tm))
}
Run Code Online (Sandbox Code Playgroud)
这看起来像编译器中的错误或者可能是已知问题?任何的想法?(我用的是1.11)
编辑:到目前为止所有的响应.根据:https://golang.org/ref/spec#Short_variable_declarations
与常规变量声明不同,短变量声明可以重新声明变量,前提是它们最初在同一个块中声明(或者如果块是函数体的参数列表)具有相同的类型,并且至少有一个非空变量是新的.因此,重新声明只能出现在多变量简短声明中.重新声明不会引入新变量; 它只是为原始分配一个新值.
这部分:
if tm, err := time.Parse(...)
Run Code Online (Sandbox Code Playgroud)
创建一个仅在语句中具有范围的新变量- 它不是您声明的tm那个变量.ifvar tm time.Time
此新变量未在其中使用if,因此您会收到错误.注意你也没有得到外层的tm分配,所以fmt.Println会打印零时间,而不是time.Parse返回.
要解决此问题:声明err并更改您if的内容:
var err error
if tm, err = time.Parse(...)
Run Code Online (Sandbox Code Playgroud)
注意这是GO中的一个微妙的事情,也是一个相当常见的错误来源.:=事实上,该语句可以与已经声明的变量和一个或多个新变量混合使用 - 如果已经声明的变量位于相同的词法范围内.然后,只有新的自动声明,:=其余的只是分配(如同=).但是,如果:=在新范围中使用,则在该范围内声明所有变量并屏蔽具有相同名称的任何外部范围变量(例如if; 在;注意if条件不在大括号内,但仍被视为如果它在{code}块内;与forGO中的其他复合语句相同.
| 归档时间: |
|
| 查看次数: |
322 次 |
| 最近记录: |