GoLang 结构体初始化的执行顺序

huangapple go评论75阅读模式
英文:

Execution order for GoLang Struct Initializer

问题

我现在是你的中文翻译助手,以下是你要翻译的内容:

想知道在Go语言中,结构体初始化的执行顺序是否是有保证的。

下面的代码是否总是会产生 obj.a == 1obj.b == 2,还是说它的行为是未指定的?

num := 0

nextNumber := func() int {
	num += 1
	return num
}

type TwoNumbers struct {
	a int
	b int
}

obj := TwoNumbers{
	a: nextNumber(),
	b: nextNumber(),
}
英文:

Was wondering if execution order for struct initialization is guaranteed in GoLang.

Does the following code always produce

obj.a == 1 and obj.b == 2 or is it unspecified behavior?

num := 0

nextNumber := func() int {
	num += 1
	return num
}

type TwoNumbers struct {
	a int
	b int
}

obj := TwoNumbers{
	a: nextNumber(),
	b: nextNumber(),
}

答案1

得分: 10

函数调用的评估顺序是指定的。

代码TwoNumbers{a: nextNumber(), b: nextNumber()}是一个复合字面表达式nextNumber()的调用是表达式中的操作数。

规范关于表达式的一般规定如下:

> ...在评估表达式、赋值或返回语句的操作数时,所有函数调用、方法调用和通信操作都按照词法从左到右的顺序进行评估。

字段a的函数调用在字段b的函数调用之前进行评估,因为字段a的函数调用位于字段b的函数调用的左侧。

评估顺序仅对函数调用、方法调用和通信操作进行了指定。编译器可以重新排序其他操作数的评估。在下面的示例中,字段a的表达式在词法上位于字段b的表达式的左侧,但是b先被评估(在当前编译器中)。

type Numbers struct{ a, b, c int }
nums := Numbers{a: num, b: nextNumber(), c: nextNumber()}
fmt.Println(nums) // 输出 {2 1 2}

在 playground 上运行

英文:

The evaluation order of the function calls is specified.

The code TwoNumbers{a: nextNumber(), b: nextNumber()} is a composite literal expression. The calls to nextNumber() are operands in the expression.

The specification says this about expressions in general:

> ... when evaluating the operands of an expression, assignment, or return statement, all function calls, method calls, and communication operations are evaluated in lexical left-to-right order.

The function call for field a is evaluated before the function call for field b because the function call for field a is to the left of the function call for field b.

The evaluation order is specified for function calls, method calls and communication operations only. The compiler can reorder the evaluation of other operands. In the following example, the expression for field a lexically to the left of the expression for field b, but b is evaluated first (in the current compiler).

type Numbers struct{ a, b, c int }
nums := Numbers{a: num, b: nextNumber(), c: nextNumber()}
fmt.Println(nums) // prints {2 1 2}

Run it on the playground

huangapple
  • 本文由 发表于 2021年11月22日 09:49:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/70060114.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定