成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Go 探討了13年,怎么解決再賦值的坑?

開發 前端
今天這篇文章給大家介紹了一個 13 年前(2009 年)就被發現的神坑。當初最早學習 Go 時,也碰到很多教程、文檔,同學會遇到這個重新賦值聲明的神坑。

大家好,我是煎魚。

最近在看 Go 的一些歷史提案時,發現有個別很神奇的提案,已經提出來了許多年,但在如今依然沒有關閉,并且不斷地有人在討論,但又解決不了。

有種 “很氣又干不掉我的樣子”,今天就由煎魚帶大家一起來看看是什么。

背景

今天本文介紹的 Go 提案《proposal: spec: various changes to :=[1]》是經典中的經典,初學者學習時常犯的問題。

該提案自 2009 年提出,最近一次的激烈討論是 2021 年:

代碼原型如下:

func f() (err os.Error) {
v, err := g()
if err != nil {
return
}
if v {
v, err := h()
if err != nil {
return
}
}
}

這段代碼的問題在于函數片段中的 := 會導致產生一個新的 err 變量,該新變量會使得返回參數(err os.Error,也聲明了 err)被覆蓋。

也就是 Go 里的 := 重新賦值的邏輯,會導致參數被覆蓋,從而引起隱藏問題,極其容易踩坑。

新提案

如開頭所說,這是一個經過了 13 年,在 2022 年依然沒有結局的提案。

煎魚總結了提案和其他討論的思路,社區一共提出了如下幾種解決方案或思路。如下:

  • 加語法糖。
  • 干掉語法。
  • 定規范。

加語法糖

這個想法刪除了重新聲明 := 語法,并添加了新的 : 和 :: 語法,用于新變量聲明。

如下代碼:

package bar

func foo() {
var x, err = f()
...
// 這里 “:err” 表示上面聲明的 err。
var y, z, :err = g()
...
{
// 實際上,:err 表示代碼區塊里的已經聲明的 err。
var w, :err = h()
...
// ::err 表示包級別聲明的 err。
var u, v, ::err = j()
...
// 這個“err”是一個新的聲明。
var m, n, err = k()
...
}
}

上述代碼中給出了三種案例,分別是:

  • var :err = x:表示最近一個作用域聲明的 err,原意是指上面一個聲明的 err,因此你會發現在代碼區塊和外,代表著不同的結果。
  • var ::err = x:表示包級別聲明的 err。
  • var err = x:表示一個新的聲明。

干掉語法

在另外一個提案《proposal: Go 2: let := support any l-value that = supports[2]》中 Go 語言之父 @ Rob Pike 直接表示想干掉 := 這個重新賦值的方式,而不是再修修補補,加一堆會更復雜。

如下圖:

我認為我們應該以消除重新聲明為目標,如果我們能夠建立一個更平穩的錯誤處理模型,那么重新聲明就變得不那么引人注目了。不過這不會很快發生。

刪除功能而不是增加功能。

(大呼:less is more)

單行多次聲明

首先修改重新賦值的語義,:= 左邊的所有標識符總是被聲明為新的變量,在同一個塊內重新聲明是不允許的。

如下代碼:

a, err := foo()
b, err := foo() // 編譯錯誤,因為 var err 已在此塊中聲明

第一行聲明正常,第二行由于在同一個代碼區塊重新聲明了,因此會出現編譯錯誤,因為已經聲明過了。

接著增加語法特性,允許在一行中混合使用 = 和 :=。如下代碼:

// a 和 err 被聲明和初始化(相當于:a, err := foo()
a:=, err:= foo()

// b 被聲明和初始化,而 err 只被賦予了一個新值
b:=, err= foo()
if true {
// c 在 if 塊中聲明并初始化,并為 err 分配一個新值
c:=, err= foo()
}
if true {
// d 和 err 在 if 塊中聲明,err 被隱藏
d:=, err:= foo()
}

允許單行進行多次聲明,本質上是明確了聲明的范圍,會提高代碼可讀性的復雜度。

總結

今天這篇文章給大家介紹了一個 13 年前(2009 年)就被發現的神坑。當初最早學習 Go 時,也碰到很多教程、文檔,同學會遇到這個重新賦值聲明的神坑。

實際上上述的 3 個方案,看起來是從不同的角度補全了這個重新聲明的語法糖,但也加大了復雜度。

也許直接干掉,也可能是個不錯的選擇?

參考資料

[1]proposal: spec: various changes to :=: https://github.com/golang/go/issues/377

[2]proposal: Go 2: let := support any l-value that = supports: https://github.com/golang/go/issues/30318

責任編輯:武曉燕 來源: 腦子進煎魚了
相關推薦

2023-03-07 08:00:12

netpollGo

2019-04-18 14:06:35

MySQL分庫分表數據庫

2022-07-31 23:05:55

Go語言短變量

2021-07-07 12:02:25

Go 服務進程

2021-10-28 19:10:02

Go語言編碼

2012-10-12 10:22:37

Surface手機微軟諾基亞

2020-10-15 08:11:56

JavaScript邏輯運算符

2024-01-18 11:24:51

行業觀察人工智能

2022-08-08 06:50:06

Go語言閉包

2022-01-03 20:13:08

Gointerface 面試

2022-08-08 08:31:55

Go 語言閉包匿名函數

2024-12-03 08:47:01

2021-03-16 08:56:35

Go interface面試

2019-12-05 08:44:20

MybatisSQL場景

2023-03-13 13:36:00

Go擴容切片

2024-05-08 16:44:40

TCPRST網絡協議

2022-09-02 16:07:02

團隊問題

2013-01-17 10:33:25

2025-04-28 01:22:00

2022-12-16 10:52:36

科技預測IT領導者
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩精品在线观看网站 | 成人免费毛片片v | 一区二区亚洲 | 国产日韩欧美在线观看 | 91资源在线观看 | 久草热在线 | 在线精品一区 | 日本一区二区三区在线观看 | 国产视频导航 | 九色porny自拍视频 | 日本三级视频 | 超碰成人免费 | 四虎永久免费影院 | 国产成人在线视频 | 欧美一区二区免费 | 欧美影院| 婷婷激情在线 | 精品国产99 | 日韩色综合 | 韩国精品在线观看 | 国产第一页在线观看 | 亚洲精品美女 | 91视频在线观看 | 国产精品综合久久 | 免费一级黄色录像 | 欧美成人激情 | 久色视频在线观看 | 国产精品久久久久无码av | 国产精品乱码一区二区三区 | 欧美精品一区二区三区在线四季 | 亚洲激情av| 国产精品久久久久久久久婷婷 | 成人在线免费电影 | 亚洲一区二区中文字幕 | 日韩网站免费观看 | 国产免费福利 | 欧美在线看片 | 在线观看欧美一区 | 视频在线h | 国产精品国产精品国产专区不片 | 亚洲精品视频三区 |