如果在 Go 中构造,则无法初始化结构
Cannot init struct in if construct in Go
当我注意到以下代码片段无法编译时,我感到非常惊讶:
aTime := time.Time{}
if defaultTime := time.Time{} ; aTime != defaultTime {}
编译器returns:
type time.Time is not an expression
defaultTime := time.Time used as
value undefined: defaultTime
这里的目的是测试 aTime 变量是否设置为默认值。
如果我得到结构的指针它也不会编译 (defaultTime := &time.Time{}).
但是,如果我在 if 构造之外初始化 defaultTime,或者使用内置的 new() 进行初始化,它会编译:
aTime := time.Time{}
if defaultTime := new(time.Time) ; aTime != *defaultTime {}
根据我到处阅读的内容,new(myStruct) 它应该完全等同于 &myStruct{}.
按照我的解释,defaultValue := time.Time{} 符合 SimpleStmt (specifically an Assignment), as detailed in the If statement spec.
尽管我尽了最大的谷歌搜索努力,但我仍未对这种行为做出任何解释。如果有人能让我的脑袋停止旋转,我将不胜感激。
{
被识别为Block
的开始,终止SimpleStmt
的解析。在做出该决定后,编译器决定,作为 SimpleStmt
,aTime := time.Time
无效,因为 time.Time
不是可以分配的值。但是,解析器尝试对 {
.
进行另一种解释可能为时已晚
带有 new
的版本可以工作,因为它不包含 {
字符,因此可以避免以这种方式混淆解析器。
您也可以通过将其括在括号中来使用文字格式,因为块不能合法地从表达式的中间开始,所以这也有效:
if defaultTime := (time.Time{}); aTime != defaultTime {
// ...
}
gofmt
给出了有用的信息 "expected boolean expression, found simple statement (missing parentheses around composite literal?)",但奇怪的是,go 编译器本身并没有。
我认为我要建议的不一定是更好的解决方案。但是对于你的用例,你可以尝试这样简洁
if !aTime.IsZero() {
// ...
}
Ymmv
当我注意到以下代码片段无法编译时,我感到非常惊讶:
aTime := time.Time{}
if defaultTime := time.Time{} ; aTime != defaultTime {}
编译器returns:
type time.Time is not an expression
defaultTime := time.Time used as
value undefined: defaultTime
这里的目的是测试 aTime 变量是否设置为默认值。
如果我得到结构的指针它也不会编译 (defaultTime := &time.Time{}).
但是,如果我在 if 构造之外初始化 defaultTime,或者使用内置的 new() 进行初始化,它会编译:
aTime := time.Time{}
if defaultTime := new(time.Time) ; aTime != *defaultTime {}
根据我到处阅读的内容,new(myStruct) 它应该完全等同于 &myStruct{}.
按照我的解释,defaultValue := time.Time{} 符合 SimpleStmt (specifically an Assignment), as detailed in the If statement spec.
尽管我尽了最大的谷歌搜索努力,但我仍未对这种行为做出任何解释。如果有人能让我的脑袋停止旋转,我将不胜感激。
{
被识别为Block
的开始,终止SimpleStmt
的解析。在做出该决定后,编译器决定,作为 SimpleStmt
,aTime := time.Time
无效,因为 time.Time
不是可以分配的值。但是,解析器尝试对 {
.
带有 new
的版本可以工作,因为它不包含 {
字符,因此可以避免以这种方式混淆解析器。
您也可以通过将其括在括号中来使用文字格式,因为块不能合法地从表达式的中间开始,所以这也有效:
if defaultTime := (time.Time{}); aTime != defaultTime {
// ...
}
gofmt
给出了有用的信息 "expected boolean expression, found simple statement (missing parentheses around composite literal?)",但奇怪的是,go 编译器本身并没有。
我认为我要建议的不一定是更好的解决方案。但是对于你的用例,你可以尝试这样简洁
if !aTime.IsZero() {
// ...
}
Ymmv