【譯】Go語(yǔ)言之聲明語(yǔ)法

作者:Rob Pike,原文鏈接:Go's Declaration Syntax

以下是譯文:


前言

Go 的初學(xué)者可能會(huì)有這樣的疑問(wèn):為什么 Go 的聲明語(yǔ)法與傳統(tǒng)的其他 C 家族編程語(yǔ)言不太一樣?在這篇文章中我們會(huì)比較這兩種不同的方式币狠,并且也會(huì)解釋為什么验辞。

C 變量

首先凶硅,讓我們說(shuō)說(shuō) C 中的語(yǔ)法悠咱。C 使用了一種不尋常的巧妙的方法來(lái)實(shí)現(xiàn)聲明語(yǔ)法峭沦。我們不是用什么特殊的語(yǔ)法來(lái)描述類型贾虽,而是寫一個(gè)表達(dá)式,這個(gè)表達(dá)式包含兩個(gè)部分:被聲明的變量和變量的類型吼鱼。

int x;

上面這行代碼聲明了一個(gè)類型為 int 的變量 x蓬豁。一般來(lái)說(shuō),為了弄清楚如何編寫新變量的類型菇肃,可以先寫一個(gè)含基本類型變量的表達(dá)式地粪,然后將基本類型放在左邊,將表達(dá)式放在右邊琐谤。

因此驶忌,下面的聲明:

int *p;
int a[3];

描述的是 p 是一個(gè)指向 int 類型的指針,因?yàn)?‘*p’ 的類型為 int笑跛。而 a 是一個(gè) int 類型的數(shù)組付魔,因?yàn)?‘a(chǎn)[3]’ (這里請(qǐng)忽略下標(biāo)的值 3,它只是說(shuō)明數(shù)組的大蟹甚濉)的類型是 int几苍。

那函數(shù)呢?在最開(kāi)始的時(shí)候陈哑,C 的函數(shù)聲明是將 參數(shù)的類型寫在括號(hào)外面的妻坝,像這樣:

int main(argc, argv)
    int argc;
    char *argv[];
{ /* ... */ }

再一次,我們可以看到 main 是一個(gè)函數(shù)惊窖,因?yàn)楸磉_(dá)式 main(argc, argv) 返回了一個(gè) int 類型的值」粝埽現(xiàn)在大家比較習(xí)慣寫成這樣:

int main(int argc, char *argv[]) { /* ... */ }

但是基本的結(jié)構(gòu)還是一樣的。

對(duì)于簡(jiǎn)單的類型來(lái)說(shuō)這種巧妙的語(yǔ)法思想是能很好工作的界酒,但是一旦類型變得復(fù)雜就會(huì)令人感到困惑了圣拄。非常經(jīng)典的一個(gè)例子就是聲明一個(gè)函數(shù)指針。遵循著規(guī)則毁欣,你得到了下面的這種寫法:

int (*fp)(int a, int b);

fp 是一個(gè)指向函數(shù)的指針庇谆,因?yàn)槿绻銓懸粋€(gè)表達(dá)式 (*fp)(a, b) 你會(huì)調(diào)用函數(shù)并得到一個(gè) int 類型的值。那如果 fp 的其中一個(gè)入?yún)⑺旧硪彩且粋€(gè)函數(shù)呢凭疮?

int (*fp)(int (*ff)(int x, int y), int b)

這就變得開(kāi)始難以閱讀了饭耳。

當(dāng)然,我們可以在聲明一個(gè)函數(shù)的時(shí)候去掉參數(shù)名执解,那么 main 函數(shù)可以聲明成:

int main(int, char *[])

讓我們回想一下寞肖,argv 是這樣聲明的,

char *agrv[]

通過(guò)把變量名放在中間來(lái)聲明類似 char *[] 這樣類型的時(shí)候其實(shí)是令人困惑的。

然后我們?cè)賮?lái)看看如果我們將入?yún)⒆兞棵サ舻那闆r下 fp 函數(shù)的聲明是怎么樣的:

int (*fp)(int (*)(int, int), int)

無(wú)論將變量名放在內(nèi)部的哪里都不那么清晰明了新蟆。對(duì)于第一個(gè)入?yún)ⅲ?/p>

int (*)(int, int)

我想這不太容易能一眼看出是在聲明一個(gè)指向函數(shù)的指針耕姊。再進(jìn)一步,如果我們的返回值也是一個(gè)函數(shù)指針呢栅葡?

int (*(*fp)(int (*)(int, int), int))(int, int)

這根本就看不清聲明出來(lái)的 fp 到底是個(gè)啥玩意茉兰。。欣簇。

你自己也可以構(gòu)造出更多這類詳細(xì)的例子规脸,但是這些都說(shuō)明了 C 的聲明語(yǔ)法可能引入的一些困難。

不過(guò)還有一點(diǎn)需要提出熊咽。因?yàn)轭愋秃吐暶鞯恼Z(yǔ)法是相同的莫鸭,所以解析中間類型的表達(dá)式是很困難的。這就是為什么 C 的類型轉(zhuǎn)換總是用括號(hào)括起來(lái):

(int)M_PI

Go 語(yǔ)法

非 C 家族的編程語(yǔ)言通常使用不同的聲明類型的語(yǔ)法:變量名通常放在前面横殴,然后緊跟著一個(gè)冒號(hào)被因。因此我們上面的例子就變成了這樣:

x: int
p: pointer to int
a: array[3] of int

這些聲明是明確的,如果從左往右讀你會(huì)發(fā)現(xiàn)也是詳細(xì)的衫仑。Go 語(yǔ)言從中得到了啟發(fā)梨与,但為了簡(jiǎn)潔起見(jiàn),刪除了冒號(hào)和一些關(guān)鍵字:

x int
p *int
a [3]int

這個(gè)例子中 [3]int 與如何在表達(dá)式中使用 a 這兩者似乎沒(méi)有直接的對(duì)應(yīng)文狱。(后面一小節(jié)中我們會(huì)講到指針的粥鞋。)你可以通過(guò)單獨(dú)的語(yǔ)法來(lái)獲得清晰的結(jié)果。

現(xiàn)在讓我們考慮下函數(shù)瞄崇。讓我們把這個(gè)聲明寫成 Go 的形式呻粹,盡管在 Go 中真正的 main 函數(shù)是沒(méi)有入?yún)⒌模?/p>

func main(argc int, argv []string) int

表面上這和 C 語(yǔ)言并沒(méi)什么不同,除了將字符數(shù)組改成了字符串形式苏研。但是從左往右讀起來(lái)卻很順暢:

函數(shù) main 需要傳入一個(gè)整型和字符串切片并且返回一個(gè)整型等浊。(譯者注:直到譯者看到這篇文章,譯者才發(fā)現(xiàn)原來(lái)這么寫讀起來(lái)竟這么順暢摹蘑。筹燕。。)

即便舍去變量名還是很明確——因?yàn)閷?duì)于類型聲明上沒(méi)有位置的變化纹蝴,所以也沒(méi)有什么困惑庄萎。

func main(int, []string) int

這種從左到右的風(fēng)格有一個(gè)優(yōu)點(diǎn):就算類型變得越來(lái)越復(fù)雜踪少,這種方式還是表現(xiàn)得很得當(dāng)塘安。

舉個(gè)聲明函數(shù)變量的例子(類似在 C 語(yǔ)言中的函數(shù)指針):

f func(func(int, int) int, int) int

或者如果 f 返回的也是一個(gè)函數(shù)(譯者注:邊寫邊讀你會(huì)再次驚訝于這絲滑般的順暢感。援奢。兼犯。):

f func(func(int, int) int, int) func(int, int) int

從左到右依然讀起來(lái)很順暢,并且當(dāng)變量名被聲明的時(shí)候也很明顯。

類型和表達(dá)式的語(yǔ)法的不同點(diǎn)使得在 Go 中編寫和調(diào)用閉包是那么的簡(jiǎn)單:

sum := func(a, b int) int { return a + b } (3, 4)

指針

指針這家伙總是表現(xiàn)得“與眾不同”一點(diǎn)切黔。觀察下數(shù)組和切片砸脊,舉個(gè)例子,Go 的類型語(yǔ)法將方括號(hào)放在類型的左邊纬霞,但是賦值表達(dá)式語(yǔ)法卻是將其放在表達(dá)式的右邊:

var a []int
x = a[1]

為了讓大家有一種熟悉的感覺(jué)凌埂,Go 的指針同樣延續(xù) C 語(yǔ)言中的 * 符號(hào),但是我們不能簡(jiǎn)單的將指針類型也反轉(zhuǎn)一下诗芜。所以指針使用方式如下:

var p *int
x = *p

我們不能簡(jiǎn)單粗暴地改成這樣:

var p *int
x = p*

因?yàn)楹缶Y * 會(huì)與乘法的 * 相混淆瞳抓。那或許我們可以使用 ^,舉個(gè)例子:

var p ^int
x = p^

但同樣的這個(gè)符號(hào)也已經(jīng)有其他含義了伏恐,類型和表達(dá)式在前綴后綴的問(wèn)題上總是在許多方面使事情復(fù)雜化孩哑。舉個(gè)例子,

[]int("hi")

這是一種寫法翠桦,但一旦以 * 打頭就必須用括號(hào)將其包缀嵫选:

(*int)(nil)

如果我們?cè)敢夥艞?* 作為指針語(yǔ)法,那么這些括號(hào)就不是必要的了销凑。(譯者注:但還能有更好的指針語(yǔ)法嗎丛晌。。斗幼。)

所以 Go 的指針語(yǔ)法與熟悉的 C 語(yǔ)言是類似的茵乱,但這個(gè)關(guān)聯(lián)也意味著我們不得不使用括號(hào)來(lái)消除語(yǔ)法中的類型和表達(dá)式之間的差異。

總體而言孟岛,我們相信 Go 的類型語(yǔ)法比 C 的要更容易理解瓶竭,尤其是當(dāng)事情變得復(fù)雜的時(shí)候。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末渠羞,一起剝皮案震驚了整個(gè)濱河市斤贰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌次询,老刑警劉巖荧恍,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異屯吊,居然都是意外死亡送巡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門盒卸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)骗爆,“玉大人,你說(shuō)我怎么就攤上這事蔽介≌叮” “怎么了煮寡?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)犀呼。 經(jīng)常有香客問(wèn)我幸撕,道長(zhǎng),這世上最難降的妖魔是什么外臂? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任坐儿,我火速辦了婚禮,結(jié)果婚禮上宋光,老公的妹妹穿的比我還像新娘挑童。我一直安慰自己,他們只是感情好跃须,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布站叼。 她就那樣靜靜地躺著,像睡著了一般菇民。 火紅的嫁衣襯著肌膚如雪尽楔。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,365評(píng)論 1 302
  • 那天第练,我揣著相機(jī)與錄音阔馋,去河邊找鬼。 笑死娇掏,一個(gè)胖子當(dāng)著我的面吹牛呕寝,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播婴梧,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼下梢,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼塞蹭!你這毒婦竟也來(lái)了孽江?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤番电,失蹤者是張志新(化名)和其女友劉穎岗屏,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體漱办,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡这刷,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了娩井。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片暇屋。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖撞牢,靈堂內(nèi)的尸體忽然破棺而出率碾,到底是詐尸還是另有隱情叔营,我是刑警寧澤屋彪,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布所宰,位于F島的核電站,受9級(jí)特大地震影響畜挥,放射性物質(zhì)發(fā)生泄漏仔粥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一蟹但、第九天 我趴在偏房一處隱蔽的房頂上張望躯泰。 院中可真熱鬧,春花似錦华糖、人聲如沸麦向。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)诵竭。三九已至,卻和暖如春兼搏,著一層夾襖步出監(jiān)牢的瞬間卵慰,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工佛呻, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留裳朋,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓吓著,卻偏偏與公主長(zhǎng)得像鲤嫡,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子绑莺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354