您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“Go中如何聲明語法”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“Go中如何聲明語法”這篇文章吧。
C 變量
首先,讓我們說說 C 中的語法。C 使用了一種不尋常的巧妙的方法來實現(xiàn)聲明語法。我們不是用什么特殊的語法來描述類型,而是寫一個表達式,這個表達式包含兩個部分:被聲明的變量和變量的類型。
int x;
上面這行代碼聲明了一個類型為 int 的變量 x。一般來說,為了弄清楚如何編寫新變量的類型,可以先寫一個含基本類型變量的表達式,然后將基本類型放在左邊,將表達式放在右邊。
因此,下面的聲明:
int *p; int a[3];
描述的是 p 是一個指向 int 類型的指針,因為 ‘*p' 的類型為 int。而 a 是一個 int 類型的數(shù)組,因為 ‘a(chǎn)[3]' (這里請忽略下標(biāo)的值 3,它只是說明數(shù)組的大?。┑念愋褪?int。
那函數(shù)呢?在最開始的時候,C 的函數(shù)聲明是將 參數(shù)的類型寫在括號外面的,像這樣:
int main(argc, argv) int argc; char *argv[]; { /* ... */ }
再一次,我們可以看到 main 是一個函數(shù),因為表達式 main(argc, argv) 返回了一個 int 類型的值?,F(xiàn)在大家比較習(xí)慣寫成這樣:
int main(int argc, char *argv[]) { /* ... */ }
但是基本的結(jié)構(gòu)還是一樣的。
對于簡單的類型來說這種巧妙的語法思想是能很好工作的,但是一旦類型變得復(fù)雜就會令人感到困惑了。非常經(jīng)典的一個例子就是聲明一個函數(shù)指針。遵循著規(guī)則,你得到了下面的這種寫法:
int (*fp)(int a, int b);
fp 是一個指向函數(shù)的指針,因為如果你寫一個表達式 (*fp)(a, b) 你會調(diào)用函數(shù)并得到一個 int 類型的值。那如果 fp 的其中一個入?yún)⑺旧硪彩且粋€函數(shù)呢?
int (*fp)(int (*ff)(int x, int y), int b)
這就變得開始難以閱讀了。
當(dāng)然,我們可以在聲明一個函數(shù)的時候去掉參數(shù)名,那么 main 函數(shù)可以聲明成:
int main(int, char *[])
讓我們回想一下,argv 是這樣聲明的,
char *agrv[]
通過把變量名放在中間來聲明類似 char *[] 這樣類型的時候其實是令人困惑的。
然后我們再來看看如果我們將入?yún)⒆兞棵サ舻那闆r下 fp 函數(shù)的聲明是怎么樣的:
int (*fp)(int (*)(int, int), int)
無論將變量名放在內(nèi)部的哪里都不那么清晰明了。對于第一個入?yún)ⅲ?/p>
int (*)(int, int)
我想這不太容易能一眼看出是在聲明一個指向函數(shù)的指針。再進一步,如果我們的返回值也是一個函數(shù)指針呢?
int (*(*fp)(int (*)(int, int), int))(int, int)
這根本就看不清聲明出來的 fp 到底是個啥玩意。。。
你自己也可以構(gòu)造出更多這類詳細的例子,但是這些都說明了 C 的聲明語法可能引入的一些困難。
不過還有一點需要提出。因為類型和聲明的語法是相同的,所以解析中間類型的表達式是很困難的。這就是為什么 C 的類型轉(zhuǎn)換總是用括號括起來:
(int)M_PI
Go 語法
非 C 家族的編程語言通常使用不同的聲明類型的語法:變量名通常放在前面,然后緊跟著一個冒號。因此我們上面的例子就變成了這樣:
x: int p: pointer to int a: array[3] of int
這些聲明是明確的,如果從左往右讀你會發(fā)現(xiàn)也是詳細的。Go 語言從中得到了啟發(fā),但為了簡潔起見,刪除了冒號和一些關(guān)鍵字:
x int p *int a [3]int
這個例子中 [3]int 與如何在表達式中使用 a 這兩者似乎沒有直接的對應(yīng)。(后面一小節(jié)中我們會講到指針的。)你可以通過單獨的語法來獲得清晰的結(jié)果。
現(xiàn)在讓我們考慮下函數(shù)。讓我們把這個聲明寫成 Go 的形式,盡管在 Go 中真正的 main 函數(shù)是沒有入?yún)⒌模?/p>
func main(argc int, argv []string) int
表面上這和 C 語言并沒什么不同,除了將字符數(shù)組改成了字符串形式。但是從左往右讀起來卻很順暢:
函數(shù) main 需要傳入一個整型和字符串切片并且返回一個整型。(譯者注:直到譯者看到這篇文章,譯者才發(fā)現(xiàn)原來這么寫讀起來竟這么順暢。。。)
即便舍去變量名還是很明確——因為對于類型聲明上沒有位置的變化,所以也沒有什么困惑。
func main(int, []string) int
這種從左到右的風(fēng)格有一個優(yōu)點:就算類型變得越來越復(fù)雜,這種方式還是表現(xiàn)得很得當(dāng)。
舉個聲明函數(shù)變量的例子(類似在 C 語言中的函數(shù)指針):
f func(func(int, int) int, int) int
或者如果 f 返回的也是一個函數(shù)(譯者注:邊寫邊讀你會再次驚訝于這絲滑般的順暢感。。。):
f func(func(int, int) int, int) func(int, int) int
從左到右依然讀起來很順暢,并且當(dāng)變量名被聲明的時候也很明顯。
類型和表達式的語法的不同點使得在 Go 中編寫和調(diào)用閉包是那么的簡單:
sum := func(a, b int) int { return a + b } (3, 4)
指針
指針這家伙總是表現(xiàn)得“與眾不同”一點。觀察下數(shù)組和切片,舉個例子,Go 的類型語法將方括號放在類型的左邊,但是賦值表達式語法卻是將其放在表達式的右邊:
var a []int x = a[1]
為了讓大家有一種熟悉的感覺,Go 的指針同樣延續(xù) C 語言中的 * 符號,但是我們不能簡單的將指針類型也反轉(zhuǎn)一下。所以指針使用方式如下:
var p *int x = *p
我們不能簡單粗暴地改成這樣:
var p *int x = p*
因為后綴 會與乘法的 相混淆。那或許我們可以使用 ^,舉個例子:
var p ^int x = p^
但同樣的這個符號也已經(jīng)有其他含義了,類型和表達式在前綴后綴的問題上總是在許多方面使事情復(fù)雜化。舉個例子,
[]int("hi")
這是一種寫法,但一旦以 * 打頭就必須用括號將其包?。?/p>
(*int)(nil)
如果我們愿意放棄 * 作為指針語法,那么這些括號就不是必要的了。(譯者注:但還能有更好的指針語法嗎。。。)
所以 Go 的指針語法與熟悉的 C 語言是類似的,但這個關(guān)聯(lián)也意味著我們不得不使用括號來消除語法中的類型和表達式之間的差異。
總體而言,我們相信 Go 的類型語法比 C 的要更容易理解,尤其是當(dāng)事情變得復(fù)雜的時候。
以上是“Go中如何聲明語法”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。