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

时间:2015-09-24 06:49:15

标签: struct go initialization

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

aTime := time.Time{}
if defaultTime := time.Time{} ; aTime != defaultTime {}

编译器返回:

  

输入time.Time不是表达式

     

defaultTime:= time.Time用作

     

值undefined:defaultTime

这里的目的是测试 aTime 变量,如果它已设置为默认值。

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

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

aTime := time.Time{}
if defaultTime := new(time.Time) ; aTime != *defaultTime {}

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

当我插入它时, defaultValue:= time.Time {} 符合SimpleStmt(特别是Assignment),详见If statement spec

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

2 个答案:

答案 0 :(得分:6)

{被识别为Block的开头,终止SimpleStmt的解析。在做出该决定后,编译器决定,SimpleStmtaTime := time.Time无效,因为time.Time不是可以分配的值。但是,对于解析器来说,尝试对{进行另一种解释可能为时已晚。

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

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

if defaultTime := (time.Time{}); aTime != defaultTime {
    // ...
}

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

答案 1 :(得分:0)

我认为我要提出的建议不一定是更好的解决方案。但是对于您的用例,您可以尝试使其简洁化

if !aTime.IsZero() {
    // ...
}

Ymmv