Go語言小細節——變量估值規則

變量與常量的估值

package main

func main() {
	var n uint = 10
	const N uint = 10
	var x byte = (1 << n) / 100
	var y byte = (1 << N) / 100
	println(x, y) // 0 10
}

程序的打印結果值爲:0,10

以上程序中,x 與 y 的輸出不同,僅僅是因爲在左移操作中,右操作數的類型不同導致的,一個爲變量,一個爲常量,具體原因如下:

  1. 上述程序,移位操作的左操作數 1 的類型爲尚未確定的類型,在編譯時,如果右操作數爲變量,那麼編輯器在移位操作的規則中判定,1 的類型爲最終程序需要賦值的變量類型,也就是 x 的類型 byte,byte 只有8位,程序需要左移10位,所以最終變量溢出,變爲0
  2. 當移位操作的右操作數爲常量時,1 還是被認爲是類型不確定的整數來進行處理,所以 1 << 10 = 1024, 1024 / 100 = 10
const N = 2
var m = 2

var _ float64 = 1 << N  // 編譯沒問題
var _ = float64(1 << N) // 編譯沒問題

// 1被推斷爲float64類型
var _ float64 = 1 << m  // 編譯失敗:浮點數不可被移位
var _ = float64(1 << m) // 編譯失敗:浮點數不可被移位

以上也是同理,當移位操作的右操作數爲常量時,編譯器會認定爲類型不確定的整數,允許移位操作,但當右操作數爲變量時,就會認定爲是 float64 類型,浮點數是不能進行移位操作的,所以程序編譯報錯。

多值賦值語句的執行規則

var a []int = nil
a, a[0] = []int{1, 2}, 9
fmt.Println(a)

以上程序會在編譯時報錯,因爲程序在執行多值賦值的時候,會進行以下兩階段:

// 第一階段
x := &a; y := a; z := 0 // x,y,z可以理解爲編譯器生成的臨時變量
// 第二階段(不影響第一階段)
*x = []int{1, 2}
y[z] = 9

所以在執行 a[0] = 9 的時候,此時的 a 還是爲 nil 的

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章