日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
Go探討了13年,怎么解決再賦值的坑?

最近在看 Go 的一些歷史提案時(shí),發(fā)現(xiàn)有個(gè)別很神奇的提案,已經(jīng)提出來了許多年,但在如今依然沒有關(guān)閉,并且不斷地有人在討論,但又解決不了。

創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于網(wǎng)站設(shè)計(jì)、成都網(wǎng)站設(shè)計(jì)、河口網(wǎng)絡(luò)推廣、重慶小程序開發(fā)、河口網(wǎng)絡(luò)營(yíng)銷、河口企業(yè)策劃、河口品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供河口建站搭建服務(wù),24小時(shí)服務(wù)熱線:18982081108,官方網(wǎng)址:www.cdcxhl.com

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

背景

今天本文介紹的 Go 提案《proposal: spec: various changes to :=[1]》是經(jīng)典中的經(jīng)典,初學(xué)者學(xué)習(xí)時(shí)常犯的問題。

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

代碼原型如下:

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

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

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

新提案

如開頭所說,這是一個(gè)經(jīng)過了 13 年,在 2022 年依然沒有結(jié)局的提案。

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

  • 加語法糖。
  • 干掉語法。
  • 定規(guī)范。

加語法糖

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

如下代碼:

package bar

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

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

  • var :err = x:表示最近一個(gè)作用域聲明的 err,原意是指上面一個(gè)聲明的 err,因此你會(huì)發(fā)現(xiàn)在代碼區(qū)塊和外,代表著不同的結(jié)果。
  • var ::err = x:表示包級(jí)別聲明的 err。
  • var err = x:表示一個(gè)新的聲明。

干掉語法

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

如下圖:

我認(rèn)為我們應(yīng)該以消除重新聲明為目標(biāo),如果我們能夠建立一個(gè)更平穩(wěn)的錯(cuò)誤處理模型,那么重新聲明就變得不那么引人注目了。不過這不會(huì)很快發(fā)生。

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

(大呼:less is more)

單行多次聲明

首先修改重新賦值的語義,:= 左邊的所有標(biāo)識(shí)符總是被聲明為新的變量,在同一個(gè)塊內(nèi)重新聲明是不允許的。

如下代碼:

a, err := foo()
b, err := foo() // 編譯錯(cuò)誤,因?yàn)?var err 已在此塊中聲明

第一行聲明正常,第二行由于在同一個(gè)代碼區(qū)塊重新聲明了,因此會(huì)出現(xiàn)編譯錯(cuò)誤,因?yàn)橐呀?jīng)聲明過了。

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

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

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

允許單行進(jìn)行多次聲明,本質(zhì)上是明確了聲明的范圍,會(huì)提高代碼可讀性的復(fù)雜度。

總結(jié)

今天這篇文章給大家介紹了一個(gè) 13 年前(2009 年)就被發(fā)現(xiàn)的神坑。當(dāng)初最早學(xué)習(xí) Go 時(shí),也碰到很多教程、文檔,同學(xué)會(huì)遇到這個(gè)重新賦值聲明的神坑。

實(shí)際上上述的 3 個(gè)方案,看起來是從不同的角度補(bǔ)全了這個(gè)重新聲明的語法糖,但也加大了復(fù)雜度。

也許直接干掉,也可能是個(gè)不錯(cuò)的選擇?

參考資料

[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


網(wǎng)站名稱:Go探討了13年,怎么解決再賦值的坑?
網(wǎng)頁地址:http://www.dlmjj.cn/article/coohoop.html