当我注意到以下片段未编译时,我感到非常惊讶:
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
尽管我用谷歌最好的谷歌搜索努力,但我还没有对这种行为做出任何解释。如果有人能让我的头停止旋转,我将不胜感激。答案 0 :(得分:6)
{
被识别为Block
的开头,终止SimpleStmt
的解析。在做出该决定后,编译器决定,SimpleStmt
,aTime := time.Time
无效,因为time.Time
不是可以分配的值。但是,对于解析器来说,尝试对{
进行另一种解释可能为时已晚。
new
的版本有效,因为它不包含{
字符,因此避免以这种方式混淆解析器。
你也可以通过将它包装在括号中来使用文字格式,因为块不能合法地从表达式的中间开始,所以这也有效:
if defaultTime := (time.Time{}); aTime != defaultTime {
// ...
}
gofmt
给出了有用的消息"期望的布尔表达式,找到了简单的语句(复合文字周围缺少括号?)",但奇怪的是,go编译器本身没有。
答案 1 :(得分:0)
我认为我要提出的建议不一定是更好的解决方案。但是对于您的用例,您可以尝试使其简洁化
if !aTime.IsZero() {
// ...
}
Ymmv