猿问

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

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


aTime := time.Time{}

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

编译器返回:


输入 time.Time 不是表达式


defaultTime := time.Time 用作


值未定义: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(特别是Assignment),如If 语句规范中详述。


尽管我尽了最大努力,但我对这种行为没有任何解释。如果有人能让我的头停止旋转,我将不胜感激。


繁华开满天机
浏览 154回答 2
2回答

青春有我

该{是公认的开始Block,终止的解析SimpleStmt。犯下这一决定之后,编译器决定,作为一个SimpleStmt,aTime := time.Time是无效的,因为time.Time没有可分配的值。但是,解析器尝试对{.版本 withnew有效,因为它不包含{字符,因此避免以这种方式混淆解析器。您还可以通过将其括在括号中来使用文字格式,因为块不能合法地从表达式的中间开始,因此这也适用:if defaultTime := (time.Time{}); aTime != defaultTime {    // ...}gofmt 给出了有用的消息“预期的布尔表达式,找到了简单的语句(复合文字周围缺少括号?)”,但奇怪的是,go 编译器本身没有。

湖上湖

我不认为我要建议的一定是更好的解决方案。但是对于您的用例,您可以尝试简洁if !aTime.IsZero() {    // ...}ymmv
随时随地看视频慕课网APP

相关分类

Go
我要回答