![](/img/trans.png)
[英]Does Go compiler's evaluation differ for constant expression and other expression
[英]What is the result of a single variable expression evaluation
運行以下 Go 代碼片段,可以發現 function foo
在評估 function 的第二個參數時接收到實際設置的第一個參數的值。 這種行為可能看起來違反直覺,因此我們需要證明這是語言規范的一部分,而不是特定於實現的東西。
package main
import (
"fmt"
)
func setVal(s *int, v int) int {
old := *s
*s = v
return old
}
func foo(s int, p int) {
fmt.Printf("s = %d, p = %d\n", s, p)
}
func main() {
var s int
foo(s, setVal(&s, 99))
}
程序輸出s = 99, p = 0
,這意味着變量s
的修改值已傳遞給 function。
這是 Go 規范關於此案的內容。
在function 調用中, ...arguments 必須是單值表達式... arguments 以通常的順序計算。 評估后,調用的參數按值傳遞給 function...其中通常的順序是詞法從左到右的順序。
變量是保存值的存儲位置。 ...通過引用表達式中的變量來檢索變量的值; 它是分配給變量的最新值。
因此foo(s, setVal(&s, 99))
是一個 function 調用,變量s
和 function setVal()
是單值表達式,首先計算s
。 最后一個規范語句假設變量評估的結果是它的值,所以如果這是真的,function foo
應該接收變量s
初始值。
但實際上似乎 function 收到了在評估第二個參數時設置的第一個參數的值,這有點令人困惑。
這是否意味着評估順序被破壞或變量評估的結果不是它的值?
您從規范中“錯過”的是Spec: 調用:
在 function 調用中, function 值和 arguments以通常的順序進行評估。 評估后,調用的參數按值傳遞給 function,被調用的 function 開始執行。
評估參數並不意味着它們的值被讀取或“獲取”。 第一個參數是s
,它的求值是s
本身,但它的值還沒有被讀取。 第二個參數被評估,這意味着setVal()
被調用並將修改s
的值。
現在我們已經評估了參數,它們的值被讀取,所以s
的值為99
。
在示例中評估s
是微不足道的,但當然這可能是一個更復雜的表達式,就像第二個參數一樣。 這是一個更復雜的例子:
s, s2 := new(int), new(int)
getFunc := func() func(s int, p int) { return foo }
first := func(a, b *int) *int { return a }
getFunc()(*first(s, s2), setVal(s, 99))
最后一個 function 的調用涉及以下步驟:
getFunc()
,它的返回值將是 function 值first()
被調用,它的返回值被取消引用; (b) setVal()
被調用,它的返回值將被使用*s
的值和s
的舊值(由setVal()
返回的值)。這將 output 與您的示例相同,請在Go Playground上嘗試。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.