最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

為什么Go語言把類型聲明放在后面?

 更新時間:2019年04月03日 09:24:13   作者:Mlib  
今天小編就為大家分享一篇關(guān)于為什么Go語言把類型聲明放在后面?,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧

關(guān)于類型,官網(wǎng)上有一段仔細地介紹了一下函數(shù)指針的部分,現(xiàn)在的設(shè)計比起 C 的語法,清晰很多。

也就是說,類型放在后面是為了更加清晰易懂。Rob Pike 曾經(jīng)在 Go 官方博客解釋過這個問題(查看原文:Go's Declaration Syntax),簡略翻譯如下(水平有限翻譯的不對的地方見諒):

引言

Go語言新人常常會很疑惑為什么這門語言的聲明語法(declaration syntax)會和傳統(tǒng)的C家族語言不同。在這篇博文里,我們會進行一個比較,并做出解答。

C 的語法

首先,先看看 C 的語法。C 采用了一種聰明而不同尋常的聲明語法。聲明變量時,只需寫出一個帶有目標變量名的表達式,然后在表達式里指明該表達式本身的類型即可。比如:

int x;

上面的代碼聲明了 x 變量,并且其類型為 int——即,表達式 x 為 int 類型。一般而言,為了指明新變量的類型,我們得寫出一個表達式,其中含有我們要聲明的變量,這個表達式運算的結(jié)果值屬于某種基本類型,我們把這種基本類型寫到表達式的左邊。所以,下述聲明:

int *p;
int a[3];

指明了 p 是一個int類型的指針,因為 *p的類型為int。而 a 是一個 int 數(shù)組,因為 a[3]的類型為 int(別管這里出現(xiàn)的索引值,它只是用于指明數(shù)組的長度)。

我們接下來看看函數(shù)聲明的情況。C 的函數(shù)聲明中關(guān)于參數(shù)的類型是寫在括號外的,像下面這樣:

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

如前所述,我們可以看到 main 之所以是函數(shù),是因為表達式 main(argc, argv) 返回 int。在現(xiàn)代記法中我們是這么寫的:

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

盡管看起來有些不同,但是基本的結(jié)構(gòu)是一樣的。

總的來看,當類型比較簡單時,C的語法顯得很聰明。但是遺憾的是一旦類型開始復雜,C的這套語法很快就能讓人迷糊了。著名的例子如函數(shù)指針,我們得按下面這樣來寫:

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

在這兒,fp 之所以是一個指針是因為如果你寫出 (*fp)(a, b) 這樣的表達式將會調(diào)用一個函數(shù),其返回 int 類型的值。如果當 fp 的某個參數(shù)本身又是一個函數(shù),情況會怎樣呢?

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

這讀起來可就點難了。

當然了,我們聲明函數(shù)時是可以不寫明參數(shù)的名稱的,因此 main 函數(shù)可以聲明為:

int main(int, char *[])

回想一下,之前 argv 是下面這樣的

char *argv[]

你有沒有發(fā)現(xiàn)你是從聲明的「中間」去掉變量名而后構(gòu)造出其變量類型的?盡管這不是很明顯,但你聲明某個 char *[]類型的變量的時候,竟然需要把名字插入到變量類型的中間。

我們再來看看,如果我們不命名 fp 的參數(shù)會怎樣:

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

這東西難懂的地方可不僅僅是要記得參數(shù)名原本是放這中間的

int (*)(int, int)

它更讓人混淆的地方還在于甚至可能都搞不清這竟然是個函數(shù)指針聲明。我們接著看看,如果返回值也是個函數(shù)指針類型又會怎么樣

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

這已經(jīng)很難看出是關(guān)于 fp 的聲明了。

你自己還可以構(gòu)建出比這更復雜的例子,但這已經(jīng)足以解釋 C 的聲明語法引入的某些復雜性了。

還有一點需要指出,由于類型語法和聲明語法是一樣的,要解析中間帶有類型的表達式可能會有些難度。這也就是為什么,C 在做類型轉(zhuǎn)換的時候總是要把類型用括號括起來的原因,像這樣

(int)M_PI

Go 的語法

非C家族的語言通常在聲明時使用一種不同的類型語法。一般是名字先出現(xiàn),然后常常跟著一個冒號。按照這樣來寫,我們上面所舉的例子就會變成下面這樣:

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

這樣的聲明即便有些冗長,當至少是清晰的——你只需從左向右讀就行。Go 語言所采用的方案就是以此為基礎(chǔ)的,但為了追求簡潔性,Go 語言丟掉了冒號并去掉了部分關(guān)鍵詞,成了下面這樣:

x int
p *int
a [3]int

在 [3]int 和表達式中 a的用法沒有直接的對應(yīng)關(guān)系(我們在下一節(jié)會回過頭來探討指針的問題)。至此,你獲得了代碼清晰性方面的提升,但付出的代價是語法上需要區(qū)別對待。

下面我們來考慮函數(shù)的問題。雖然在 Go 語言里,main 函數(shù)實際上沒有參數(shù),但是我們先謄抄一下之前的 main 函數(shù)的聲明:

func main(argc int, argv *[]byte) int

粗略一看和 C 沒什么不同,不過自左向右讀的話還不錯。

main 函數(shù)接受一個 int 和一個指針并返回一個int。

如果此時把參數(shù)名去掉,它還是很清楚——因為參數(shù)名總在類型的前面,所以不會引起混淆。

func main(int, *[]byte) int

這種自左向右風格的聲明的一個價值在于,當類型變得更復雜時,它依然相對簡單。下面是一個函數(shù)變量的聲明(相當于 C 語言里的函數(shù)指針)

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

或者當它返回一個函數(shù)時:

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

上面的聲明讀起來還是很清晰,自左向右,而且究竟哪一個變量名是當前被聲明的也容易看懂——因為變量名永遠在首位。

類型語法和表達式語法帶來的差別使得在 Go 語言里調(diào)用閉包也變得更簡單:

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

指針

指針有些例外。注意在數(shù)組 (array )和切片 (slice) 中,Go 的類型語法把方括號放在了類型的左邊,但是在表達式語法中卻又把方括號放到了右邊:

var a []int
x = a[1]

類似的,Go 的指針沿用了 C 的 * 記法,但是我們寫的時候也是聲明時 * 在變量名右邊,但在表達式中卻又得把 * 放到左左邊:

var p *int
x = *p

不能寫成下面這樣

var p *int
x = p*

因為后綴的 * 可能會和乘法運算混淆,也許我們可以改用 Pascal 的 ^ 標記,像這樣

var p ^int
x = p^

我們也許還真的應(yīng)該把 * 像上面這樣改成 ^ (當然這么一改 xor 運算的符號也得改),因為在類型和表達式中的 * 前綴確實把好些事兒都搞得有點復雜,舉個例子來說,雖然我們可以像下面這樣寫

[]int("hi")

但在轉(zhuǎn)換時,如果類型是以 * 開頭的,就得加上括號:

(*int)(nil)

如果有一天我們愿意放棄用 *作為指針語法的話,那么上面的括號就可以省略了。

可見,Go 的指針語法是和 C 相似的。但這種相似也意味著我們無法徹底避免在文法中有時為了避免類型和表達式的歧義需要補充括號的情況。

總而言之,盡管存在不足,但我們相信 Go 的類型語法要比 C 的容易懂。特別是當類型比較復雜時。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請查看下面相關(guān)鏈接

相關(guān)文章

  • 一起聊聊Go語言中的語法糖的使用

    一起聊聊Go語言中的語法糖的使用

    語法糖通常是用來簡化代碼編寫的,特性就是使用語法糖前后編譯的結(jié)果是相同的。這篇文章主要就來和大家一起聊聊Go語言中的語法糖的實現(xiàn)
    2022-07-07
  • 淺析Go常量為什么只支持基本數(shù)據(jù)類型

    淺析Go常量為什么只支持基本數(shù)據(jù)類型

    這篇文章主要來和大家一起討論一下Golang中常量為什么只支持基本數(shù)據(jù)類型,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起了解一下
    2023-09-09
  • Go中map數(shù)據(jù)類型的實現(xiàn)

    Go中map數(shù)據(jù)類型的實現(xiàn)

    本文介紹了Go語言中的map數(shù)據(jù)類型,用于高效地存儲和管理鍵值對,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-12-12
  • Go語言異常處理error、panic、recover的使用

    Go語言異常處理error、panic、recover的使用

    GO語言中引入的異常的處理方式為error、panic、recover ,本文主要介紹了Go語言異常處理error、panic、recover的使用,感興趣的可以了解一下
    2024-08-08
  • 使用GO操作MongoDB的方法

    使用GO操作MongoDB的方法

    這篇文章主要介紹了使用GO操作MongoDB,包括安裝MongoDB驅(qū)動程序連接mongodb的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • Go語言字符串操作指南:簡單易懂的實戰(zhàn)技巧

    Go語言字符串操作指南:簡單易懂的實戰(zhàn)技巧

    本文將介紹Go語言中字符串的實戰(zhàn)操作,通過本文的學習,讀者將掌握Go語言中字符串的常用操作,為實際開發(fā)提供幫助,需要的朋友可以參考下
    2023-10-10
  • golang的時區(qū)和神奇的time.Parse的使用方法

    golang的時區(qū)和神奇的time.Parse的使用方法

    這篇文章主要介紹了golang的時區(qū)和神奇的time.Parse的使用方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-04-04
  • GoFrame基于性能測試得知grpool使用場景

    GoFrame基于性能測試得知grpool使用場景

    這篇文章主要為大家介紹了GoFrame基于性能測試得知grpool使用場景示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • Go創(chuàng)建一個包并使用(導入本地包和注意事項)

    Go創(chuàng)建一個包并使用(導入本地包和注意事項)

    有時候需要自己寫一個包方便多次使用,但是在導入自己寫的包時遇到了問題,本文主要介紹了Go創(chuàng)建一個包并使用(導入本地包和注意事項),感興趣的可以了解一下
    2023-11-11
  • Golang的性能優(yōu)化和調(diào)試技巧

    Golang的性能優(yōu)化和調(diào)試技巧

    在開發(fā)和部署Go語言應(yīng)用程序時,性能優(yōu)化和調(diào)試是至關(guān)重要的,篇博客將介紹一些常用的Golang性能優(yōu)化和調(diào)試技巧,幫助您提升應(yīng)用程序的性能并解決潛在的問題
    2023-05-05

最新評論

城固县| 昭通市| 阿合奇县| 松桃| 临沭县| 隆子县| 泰宁县| 台东县| 鄂托克旗| 库尔勒市| 普定县| 广宗县| 洞头县| 和田市| 广昌县| 开阳县| 新民市| 泊头市| 浏阳市| 芒康县| 江津市| 荥经县| 五华县| 昂仁县| 志丹县| 昌宁县| 巴林左旗| 乌拉特中旗| 临漳县| 浑源县| 榆林市| 措美县| 云南省| 阿勒泰市| 上林县| 浮山县| 紫阳县| 勃利县| 姚安县| 吐鲁番市| 丰宁|