Go 為什麼不支援字首自增運算子?

煎魚發表於2022-06-28

大家好,我是煎魚。

習慣性對比,類比學習,是大家掌握新技能時會習慣性的關聯操作。像 Go 這種比較有味道的程式語言,其有一個細節也是大家很好奇的。

其實 Go 只支援後自增/自減,今天煎魚和大家一起研究為什麼。

語法

基本的 Go 自增,非常簡單。直接見程式碼:

a := 1
a++

fmt.Println(a)

輸出結果:

2

如果回答輸出結果錯了,建議右拐語法了。接下來看看其他幾個例子,與你預想的執行結果是否一致。

例子 1,程式碼如下:

func main() {
    a := 1
    b := a++
    fmt.Println(b)
}

輸出的結果:

# command-line-arguments
./main.go:9:8: syntax error: unexpected ++ at end of statement

例子 2,程式碼如下:

func main() {
    a := 1
    ++a
    fmt.Println(a)
}

輸出的結果:

# command-line-arguments
./main.go:9:2: syntax error: unexpected ++, expecting }

你會發現這兩個例子,在其他常見語言中都是正常的。但在 Go 中竟然會執行錯誤?

原因

Go 在設計上:

  1. 沒有支援字首自增自減的運算語句,也就是不允許 ++a。
  2. 運算子 ++ 和 -- 只能作為一個語句來使用,不可以作為表示式被賦值給其它的變數使用。

參照以下例子:

  • 在語句中,++ 是可以的。
  • 在賦值 = 中 ++ 是不可以。

那為什麼就不支援了呢?本質上 Go 的設計者是為了讓程式碼擁有更好的可讀性,也不需要糾結求值順序了。

單從程式上來看,區分字首自增,還是字尾自增,執行結果上都是一樣的。但一旦引入,會加大程式設計師的犯錯可能性,經常會有人混淆,偶爾還會有人搞成面試題來考考應聘者。

顯然,不支援字首和賦值,++、-- 僅作為一個語句能夠在 Go 程式碼上起到可讀性提高的作用,簡化意義重大。

總結

今天這篇文章,我們針對 Go 語法設計中的 ++、-- 這個細節進行了摸索和討論。實際上 a++,還是 --a,又或是更加複雜的混合表示式,更多的只能在面試或編寫時迷惑後來的小夥伴。

在 Go 工程化的道路上並不能帶來過多的收益,所以自然也就被拿掉了。

你有沒有試過被各種奇怪的字首、字尾、混合迷惑過呢?

文章持續更新,可以微信搜【腦子進煎魚了】閱讀,本文 GitHub github.com/eddycjy/blog 已收錄,學習 Go 語言可以看 Go 學習地圖和路線,歡迎 Star 催更。

Go 圖書系列

推薦閱讀

參考

  • Go FAQ
  • 為什麼go語言語法要這樣設計呢?
  • go 語言的 ++ 操作。沒有自增操作?

相關文章