4

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 Answer 1

10

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.