如果在Go中构造,则无法初始化结构

And*_*son 0 struct initialization go

当我注意到以下代码片段未编译时,我感到非常惊讶:

aTime := time.Time{}
if defaultTime := time.Time{} ; aTime != defaultTime {}
Run Code Online (Sandbox Code Playgroud)

编译器返回:

输入time.Time不是表达式

defaultTime:= time.Time用作

value undefined:defaultTime

这里的目的是测试aTime变量是否设置为默认值.

如果我得到struct的指针(defaultTime:=&time.Time {}),它也不会编译.

但是,如果我在if构造之外初始化defaultTime,或者使用new()内置函数执行init,它会编译:

aTime := time.Time{}
if defaultTime := new(time.Time) ; aTime != *defaultTime {}
Run Code Online (Sandbox Code Playgroud)

从我到处读到的,新的(myStruct)它应该完全等同于&myStruct {}.

当我插入它时,defaultValue:= time.Time {}有资格作为SimpleStmt(特别是一个赋值),详见If语句规范.

尽管谷歌最好的谷歌搜索努力,我还没有对这种行为做出任何解释.如果有人能让我的头停止旋转,将不胜感激.

hob*_*bbs 6

{被认为是a的开始Block,终止了解析SimpleStmt.犯下这一决定之后,编译器决定,作为一个SimpleStmt,aTime := time.Time是无效的,因为time.Time没有可分配的值.然而,对于解析器来说,尝试另一种解释可能为时已晚{.

有效的版本,new因为它不包含{字符,因此避免以这种方式混淆解析器.

你也可以通过将它包装在括号中来使用文字格式,因为块不能合法地在表达式的中间开始,所以这也有效:

if defaultTime := (time.Time{}); aTime != defaultTime {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

gofmt 给出了有用的消息"期望的布尔表达式,找到了简单的语句(复合文字周围缺少括号?)",但奇怪的是,go编译器本身没有.

  • 此信息可在复合文字部分(https://golang.org/ref/spec#Composite_literals)的最后几段中的Go规范中找到.找到"解析歧义出现时"跳到右侧段落. (4认同)