新聞中心
本文轉(zhuǎn)載自微信公眾號(hào)「腦子進(jìn)煎魚(yú)了」,作者陳煎魚(yú)。轉(zhuǎn)載本文請(qǐng)聯(lián)系腦子進(jìn)煎魚(yú)了公眾號(hào)。

成都創(chuàng)新互聯(lián)公司服務(wù)項(xiàng)目包括霍林郭勒網(wǎng)站建設(shè)、霍林郭勒網(wǎng)站制作、霍林郭勒網(wǎng)頁(yè)制作以及霍林郭勒網(wǎng)絡(luò)營(yíng)銷(xiāo)策劃等。多年來(lái),我們專(zhuān)注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,霍林郭勒網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶(hù)以成都為中心已經(jīng)輻射到霍林郭勒省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶(hù)的支持與信任!
大家好,我是煎魚(yú)。
前段時(shí)間看到大家在吵一個(gè)話(huà)題,那就是 Go 語(yǔ)言的類(lèi)型聲明,摳知識(shí)摳的非常細(xì)了,就是為什么他要放在后面,展開(kāi)了熱烈的討論。
示例代碼如下:
- var a []string
- var b []string
其實(shí)在早年 Go 官方估計(jì)已經(jīng)被問(wèn)煩了,寫(xiě)過(guò)一篇《Go's Declaration Syntax[1]》來(lái)具體介紹和說(shuō)明情況。
為此煎魚(yú)將參考并結(jié)合這篇官方資料,帶大家一起了解為什么 Go 如此的 “與眾不同” ,為什么要把類(lèi)型放在后面。
類(lèi)型前置
在業(yè)內(nèi)目前有不少知名語(yǔ)言,也采取的是在聲明變量類(lèi)型時(shí),把類(lèi)型定義在名字前面。像是 C、C++、C#、Java 等:
- int x;
- int x = 100;
基本的格式定義: ;。
上面的聲明是一個(gè)簡(jiǎn)單的例子,如果更復(fù)雜一些,Go 官方還給出了著名的函數(shù)指針的例子:
- int (*fp)(int a, int b);
更進(jìn)一步,如果返回值也是個(gè)函數(shù)指針類(lèi)型,就會(huì)變成:
- int (*(*fp)(int (*)(int, int), int))(int, int)
這已經(jīng)很難看出來(lái)是個(gè) fp 的聲明了。
類(lèi)型后置
前面所舉例的類(lèi)型前置的編程語(yǔ)言,很多都是 C 系列中的一者。類(lèi)型后置的代表,分別有:Go、Rust、Scala、Kotlin 等。
其實(shí)在很多類(lèi)型后置的編程語(yǔ)言種,會(huì)采取變量名+冒號(hào)+類(lèi)型的方式出現(xiàn)。就像 Rust 一樣:
- let x: i32;
- var a []string
基本的格式定義:
- x: int
- p: pointer to int
- a: array[3] of int
Go 官方參照了這類(lèi)類(lèi)型后置的設(shè)計(jì),并且為了簡(jiǎn)潔,進(jìn)一步去掉了冒號(hào)和一些關(guān)鍵字,變成:
- var a []string
我們?cè)倏椿厍懊?fp 的聲明的例子:
- int (*(*fp)(int (*)(int, int), int))(int, int)
再對(duì)比 Go 語(yǔ)言中就變成了:
f func(func(int,int) int, int) func(int, int) int
兩者一對(duì)比,Go 語(yǔ)言代碼可讀性確實(shí)更高一些。
思考
后置類(lèi)別
在類(lèi)型聲明上,實(shí)際上分為:變量類(lèi)型后置、函數(shù)返回值后置。兩者共同構(gòu)建了前置還是后置,總不能一個(gè)前置,一個(gè)后置吧,那得多么的難受。
上方 C 語(yǔ)言和 Go 語(yǔ)言函數(shù)指針的例子,所對(duì)比帶來(lái)的代碼可讀性提高,其實(shí)本質(zhì)上是由函數(shù)返回值后置所帶來(lái)的。
和類(lèi)型前置、后置沒(méi)太多直接關(guān)系。
核心思想
在類(lèi)型后置上來(lái)講,Go 官方核心思想是:這種聲明方式(從左到右的風(fēng)格)的一個(gè)優(yōu)點(diǎn)是,當(dāng)類(lèi)型變得更加復(fù)雜時(shí),它的效果非常好(One merit of this left-to-right style is how well it works as the types become more complex)。
Go 的變量名總是在前,在人的代碼閱讀上可以保持從左到右閱讀,不需要像 C 語(yǔ)言一樣在一大堆聲明中用技巧找變量名對(duì)應(yīng)的類(lèi)型。
The Clockwise/Spiral Rule
為此甚至有人寫(xiě)了篇 C 語(yǔ)言的順時(shí)針讀法《The Clockwise/Spiral Rule[2]》,有興趣可以閱讀。
如此一對(duì)比,Go 語(yǔ)言的類(lèi)型后置在復(fù)雜場(chǎng)景下與 C 語(yǔ)言的對(duì)比確實(shí)更好一些。
其他因素
類(lèi)型推導(dǎo)
諸如在類(lèi)型推導(dǎo)的形式上也會(huì)更直觀:
- func main() {
- var s1 := "腦子進(jìn)煎魚(yú)了"
- var s2 string
- }
也是一個(gè)可讀性提高的問(wèn)題。
類(lèi)型和名字誰(shuí)更重要
不同設(shè)計(jì)者對(duì)誰(shuí)更重要的理解也不一樣。是類(lèi)型更重要,還是名字更重要呢?
有的人認(rèn)為是類(lèi)型,有的人認(rèn)為是名字。這就真的是千人千面,眾口難調(diào)了。
C# 的后悔
我們看看其他語(yǔ)言,C# 設(shè)計(jì)組成員之一,其實(shí)在《Sharp Regrets: Top 10 Worst C# Features[3]》中的第五點(diǎn)表達(dá)了個(gè)人對(duì)類(lèi)型前置、后置的設(shè)計(jì)教訓(xùn)。
核心觀點(diǎn)是:從編程和數(shù)學(xué)兩方面來(lái)看,都有一個(gè)約定,即計(jì)算的結(jié)果在右側(cè)表示,所以在類(lèi) C 語(yǔ)言中,類(lèi)型在左側(cè)是很奇怪的。
在設(shè)計(jì)時(shí),C# 本來(lái)計(jì)劃把類(lèi)型注釋放在右邊。但考慮到類(lèi) C 語(yǔ)言,因此遵循了其他語(yǔ)言的慣例。
總結(jié)
實(shí)際上該問(wèn)題的研討,在 2021 年的現(xiàn)在,大部分 case 都一一被反駁了。類(lèi)型后置也不是一個(gè)與眾不同的設(shè)計(jì),很多語(yǔ)言都是如此。但既然要討論 Go 語(yǔ)言,那更多的是站在設(shè)計(jì)者的角度去考慮。
結(jié)合 Go 所提供的官方資料,在當(dāng)年的目的更多的是為了在遇到復(fù)雜類(lèi)型定義時(shí),能保持一定的代碼可讀性。
當(dāng)然,這不可否認(rèn)肯定包含 Go 開(kāi)發(fā)團(tuán)隊(duì)的主觀意識(shí)。有興趣的可以具體挖挖背后的信息。
如果是你,你會(huì)希望類(lèi)型放在前面,還是后面呢,為什么?
參考資料
[1]Go's Declaration Syntax: https://go.dev/blog/declaration-syntax
[2]The Clockwise/Spiral Rule: http://c-faq.com/decl/spiral.anderson.html
[3]Sharp Regrets: Top 10 Worst C# Features: https://www.informit.com/articles/article.aspx?p=2425867
新聞標(biāo)題:為什么Go語(yǔ)言把類(lèi)型放在后面?
地址分享:http://www.5511xx.com/article/dhjjheo.html


咨詢(xún)
建站咨詢(xún)
