是否保证成员调用之间的go求值顺序?

是否保证成员调用之间的go求值顺序?,go,expression-evaluation,Go,Expression Evaluation,假设我有一个带状态的结构,该结构上有几个成员函数。 假设struct成员返回自己类型的实例,我在该实例上调用其他函数,并将在初始实例上调用其他成员的结果作为参数传递。 第一次调用和参数调用之间的调用顺序是否得到保证 (当尝试构建具有某些内部状态(如表达式堆栈)的“生成器”类型对象时,经常会出现这种模式。) 具体来说,s.a()与s.getVal()的相对调用顺序是否得到保证? Golang定义了“词汇从左到右的顺序”,但仅适用于单个表达式,s.a().b()从技术上讲,它似乎与s.getVal(

假设我有一个带状态的结构,该结构上有几个成员函数。 假设struct成员返回自己类型的实例,我在该实例上调用其他函数,并将在初始实例上调用其他成员的结果作为参数传递。 第一次调用和参数调用之间的调用顺序是否得到保证

(当尝试构建具有某些内部状态(如表达式堆栈)的“生成器”类型对象时,经常会出现这种模式。)

具体来说,
s.a()
s.getVal()
的相对调用顺序是否得到保证? Golang定义了“词汇从左到右的顺序”,但仅适用于单个表达式,
s.a().b()
从技术上讲,它似乎与
s.getVal()
不同

它目前的行为是我想要和期待的行为,但我无法判断它是否也是我可以“永远”依赖的行为。

相关部分是:

所有函数调用、方法调用和通信操作都是按从左到右的顺序进行计算的

在包级别,初始化依赖项覆盖各个初始化表达式的从左到右规则,但不覆盖每个表达式中的操作数:


规范很容易遵循:一个goroutine中的求值顺序是有保证的——我想不出哪种语言不是这样的。如果执行顺序未知,程序将无法运行。此外,他们还表示,在Go 1.x的任何版本下,今天运行的程序都不会停止工作。更改求值行为的顺序显然会违背这一承诺。尽管值得指出的是,任何严重依赖求值顺序的代码都不必要地难以被任何阅读它的开发人员理解,而且设计应该进行重构,以使其更易于理解,且不易出错。是的,但是整个文档太长,无法粘贴到注释中,这就是我链接到它的原因。感谢Flimzy确认函数调用部分仍然适用于不同的值,这些值对于编译器来说似乎是独立的。这当然意味着编译器无法进行大量优化,但对于具有任意副作用的语言来说,这似乎是一种正确的权衡。(这就是为什么我通常更喜欢排序不重要或显式的语言,比如Haskell。)
package main

import (
    "fmt"
)

type q struct {
    val int
}

func (s *q) getVal() int {
    return s.val
}

func (s *q) a() *q {
    s.val += 1
    return s
}

func (s *q) b(i int) int {
    return i + s.val
}

func main() {
    s := &q{}
    // this currently prints 2
    // but is that guaranteed?
    fmt.Println(s.a().b(s.getVal()))
}