首页 > 解决方案 > 是否保证成员调用之间的评估顺序?

问题描述

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

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

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()))
}

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

它目前的行为是我想要和期望的行为,但我不知道这是否也是我可以“永远”依赖的行为。

标签: goexpression-evaluation

解决方案


规范的相关部分是:

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

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


推荐阅读