英文:
Struct initialization in if statements
问题
我想检查一个结构体是否为空,即其所有字段是否都设置为它们的默认值。以下代码可以正常工作:
package main
import "fmt"
type MyStruct struct {
field1 string
field2 int
}
func main() {
var mine MyStruct
empty := MyStruct{}
// 检查 mine 是否为空。
if mine == empty {
fmt.Print("mine is empty")
}
}
我想简化一下,所以将空结构体的初始化移到了 if 语句中:
func main() {
var mine MyStruct
// 检查 mine 是否为空。
if mine == MyStruct{} {
fmt.Print("mine is empty")
}
}
但是这样不起作用:syntax error: unexpected }, expecting := or = or comma
。即使下面的代码看起来几乎和第一个示例相同,也不起作用:
func main() {
var mine MyStruct
// 检查 mine 是否为空。
if empty := MyStruct{}; mine == empty {
fmt.Print("mine is empty")
}
}
编译器报错:syntax error: need trailing comma before newline in composite literal
。然而,我发现下面的代码可以工作:
func main() {
var mine MyStruct
// 检查 mine 是否为空。
if mine == *new(MyStruct) {
fmt.Print("mine is empty")
}
}
有人能解释一下为什么上面两个示例被编译器拒绝吗?顺便问一下:检查一个“空”结构体的惯用方式是什么?最后一个示例可以工作,但对我来说看起来有点奇怪。
英文:
I want to check if a struct is empty, i.e. if all of its fields are set to their default value. The following works as expected:
package main
import "fmt"
type MyStruct struct {
field1 string
field2 int
}
func main() {
var mine MyStruct
empty := MyStruct{}
// Check if mine is empty.
if mine == empty {
fmt.Print("mine is empty")
}
}
I wanted to shorten this a bit so I moved the empty struct initialization into the if statement:
func main() {
var mine MyStruct
// Check if mine is empty.
if mine == MyStruct{} {
fmt.Print("mine is empty")
}
}
But that does not work: syntax error: unexpected }, expecting := or = or comma
. Even the following does not work although it seems almost the same as the first example:
func main() {
var mine MyStruct
// Check if mine is empty.
if empty := MyStruct{}; mine == empty {
fmt.Print("mine is empty")
}
}
The compiler says: syntax error: need trailing comma before newline in composite literal
. I found the following code to work, however:
func main() {
var mine MyStruct
// Check if mine is empty.
if mine == *new(MyStruct) {
fmt.Print("mine is empty")
}
}
Can someone explain why the two above examples are not accepted by the compiler? And while we're at it: What's the idiomatic way to check for an "empty" struct? The last example works but looks a bit odd to me.
答案1
得分: 17
使用括号解决{}
的歧义。例如,
package main
import "fmt"
type MyStruct struct {
field1 string
field2 int
}
func main() {
var mine MyStruct
// 检查 mine 是否为空。
if mine == (MyStruct{}) {
fmt.Print("mine is empty")
}
}
当一个使用TypeName形式的LiteralType的复合字面量出现在关键字和if、for或switch语句的左花括号之间作为操作数时,会出现解析歧义,而且该复合字面量没有被括号、方括号或花括号包围。在这种罕见情况下,字面量的左花括号会被错误地解析为引入语句块的左花括号。为了解决这个歧义,复合字面量必须出现在括号内。
英文:
Resolve the {}
ambiguity with parentheses. For example,
package main
import "fmt"
type MyStruct struct {
field1 string
field2 int
}
func main() {
var mine MyStruct
// Check if mine is empty.
if mine == (MyStruct{}) {
fmt.Print("mine is empty")
}
}
> The Go Programming Language Specification
>
> Composite literals
>
> A parsing ambiguity arises when a composite literal using the TypeName
> form of the LiteralType appears as an operand between the keyword and
> the opening brace of the block of an "if", "for", or "switch"
> statement, and the composite literal is not enclosed in parentheses,
> square brackets, or curly braces. In this rare case, the opening brace
> of the literal is erroneously parsed as the one introducing the block
> of statements. To resolve the ambiguity, the composite literal must
> appear within parentheses.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论