簡體   English   中英

單變量表達式求值的結果是什么

[英]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 的調用涉及以下步驟:

  • 評估 function 值: getFunc() ,它的返回值將是 function 值
  • 評估參數: (a) first()被調用,它的返回值被取消引用; (b) setVal()被調用,它的返回值將被使用
  • 現在取值: *s的值和s的舊值(由setVal()返回的值)。

這將 output 與您的示例相同,請在Go Playground上嘗試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM