欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

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

引言

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

C 的語(yǔ)法

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

int x;

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

int *p;
int a[3];

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

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

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

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

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

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

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

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

在這兒,fp 之所以是一個(gè)指針是因?yàn)槿绻銓懗?(*fp)(a, b) 這樣的表達(dá)式將會(huì)調(diào)用一個(gè)函數(shù),其返回 int 類型的值。如果當(dāng) fp 的某個(gè)參數(shù)本身又是一個(gè)函數(shù),情況會(huì)怎樣呢?

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

這讀起來(lái)可就點(diǎn)難了。

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

int main(int, char *[])

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

char *argv[]

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

我們?cè)賮?lái)看看,如果我們不命名 fp 的參數(shù)會(huì)怎樣:

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

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

int (*)(int, int)

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

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

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

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

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

(int)M_PI

Go 的語(yǔ)法

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

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

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

x int
p *int
a [3]int

在 [3]int 和表達(dá)式中 a的用法沒(méi)有直接的對(duì)應(yīng)關(guān)系(我們?cè)谙乱还?jié)會(huì)回過(guò)頭來(lái)探討指針的問(wèn)題)。至此,你獲得了代碼清晰性方面的提升,但付出的代價(jià)是語(yǔ)法上需要區(qū)別對(duì)待。

下面我們來(lái)考慮函數(shù)的問(wèn)題。雖然在 Go 語(yǔ)言里,main 函數(shù)實(shí)際上沒(méi)有參數(shù),但是我們先謄抄一下之前的 main 函數(shù)的聲明:

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

粗略一看和 C 沒(méi)什么不同,不過(guò)自左向右讀的話還不錯(cuò)。

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

如果此時(shí)把參數(shù)名去掉,它還是很清楚——因?yàn)閰?shù)名總在類型的前面,所以不會(huì)引起混淆。

func main(int, *[]byte) int

這種自左向右風(fēng)格的聲明的一個(gè)價(jià)值在于,當(dāng)類型變得更復(fù)雜時(shí),它依然相對(duì)簡(jiǎn)單。下面是一個(gè)函數(shù)變量的聲明(相當(dāng)于 C 語(yǔ)言里的函數(shù)指針)

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

或者當(dāng)它返回一個(gè)函數(shù)時(shí):

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

上面的聲明讀起來(lái)還是很清晰,自左向右,而且究竟哪一個(gè)變量名是當(dāng)前被聲明的也容易看懂——因?yàn)樽兞棵肋h(yuǎn)在首位。

類型語(yǔ)法和表達(dá)式語(yǔ)法帶來(lái)的差別使得在 Go 語(yǔ)言里調(diào)用閉包也變得更簡(jiǎn)單:

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

指針

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

var a []int
x = a[1]

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

var p *int
x = *p

不能寫成下面這樣

var p *int
x = p*

因?yàn)楹缶Y的 * 可能會(huì)和乘法運(yùn)算混淆,也許我們可以改用 Pascal 的 ^ 標(biāo)記,像這樣

var p ^int
x = p^

我們也許還真的應(yīng)該把 * 像上面這樣改成 ^ (當(dāng)然這么一改 xor 運(yùn)算的符號(hào)也得改),因?yàn)樵陬愋秃捅磉_(dá)式中的 * 前綴確實(shí)把好些事兒都搞得有點(diǎn)復(fù)雜,舉個(gè)例子來(lái)說(shuō),雖然我們可以像下面這樣寫

[]int("hi")

但在轉(zhuǎn)換時(shí),如果類型是以 * 開(kāi)頭的,就得加上括號(hào):

(*int)(nil)

如果有一天我們?cè)敢夥艞売?*作為指針語(yǔ)法的話,那么上面的括號(hào)就可以省略了。

可見(jiàn),Go 的指針語(yǔ)法是和 C 相似的。但這種相似也意味著我們無(wú)法徹底避免在文法中有時(shí)為了避免類型和表達(dá)式的歧義需要補(bǔ)充括號(hào)的情況。

總而言之,盡管存在不足,但我們相信 Go 的類型語(yǔ)法要比 C 的容易懂。特別是當(dāng)類型比較復(fù)雜時(shí)。

總結(jié)

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

相關(guān)文章

  • Golang內(nèi)存泄漏場(chǎng)景以及解決方案詳析

    Golang內(nèi)存泄漏場(chǎng)景以及解決方案詳析

    golang中內(nèi)存泄露的發(fā)現(xiàn)與排查一直是來(lái)是go開(kāi)發(fā)者頭疼的一件事,下面這篇文章主要給大家介紹了關(guān)于Golang內(nèi)存泄漏場(chǎng)景以及解決的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-01-01
  • Golang時(shí)間處理庫(kù)go-carbon?v2.2.13發(fā)布細(xì)則

    Golang時(shí)間處理庫(kù)go-carbon?v2.2.13發(fā)布細(xì)則

    這篇文章主要為大家介紹了Golang?時(shí)間處理庫(kù)go-carbon?v2.2.13發(fā)布細(xì)則,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • 深入解析Go語(yǔ)言中crypto/subtle加密庫(kù)

    深入解析Go語(yǔ)言中crypto/subtle加密庫(kù)

    本文主要介紹了深入解析Go語(yǔ)言中crypto/subtle加密庫(kù),詳細(xì)介紹crypto/subtle加密庫(kù)主要函數(shù)的用途、工作原理及實(shí)際應(yīng)用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-02-02
  • golang中拿slice當(dāng)queue和拿list當(dāng)queue使用分析

    golang中拿slice當(dāng)queue和拿list當(dāng)queue使用分析

    這篇文章主要為大家介紹了golang?中拿slice當(dāng)queue和拿list當(dāng)queue使用分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • Go語(yǔ)言字符串高效拼接的實(shí)現(xiàn)

    Go語(yǔ)言字符串高效拼接的實(shí)現(xiàn)

    這篇文章主要介紹了Go語(yǔ)言字符串高效拼接的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • 利用Go實(shí)現(xiàn)一個(gè)簡(jiǎn)易DAG服務(wù)的示例代碼

    利用Go實(shí)現(xiàn)一個(gè)簡(jiǎn)易DAG服務(wù)的示例代碼

    DAG的全稱是Directed Acyclic Graph,即有向無(wú)環(huán)圖,DAG廣泛應(yīng)用于表示具有方向性依賴關(guān)系的數(shù)據(jù),如任務(wù)調(diào)度、數(shù)據(jù)處理流程、項(xiàng)目管理以及許多其他領(lǐng)域,下面,我將用Go語(yǔ)言示范如何實(shí)現(xiàn)一個(gè)簡(jiǎn)單的DAG服務(wù),需要的朋友可以參考下
    2024-03-03
  • Go 請(qǐng)求兔子識(shí)別接口實(shí)現(xiàn)流程示例詳解

    Go 請(qǐng)求兔子識(shí)別接口實(shí)現(xiàn)流程示例詳解

    這篇文章主要為大家介紹了Go 請(qǐng)求兔子識(shí)別接口實(shí)現(xiàn)流程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • Go語(yǔ)言開(kāi)發(fā)瀏覽器視頻流rtsp轉(zhuǎn)webrtc播放

    Go語(yǔ)言開(kāi)發(fā)瀏覽器視頻流rtsp轉(zhuǎn)webrtc播放

    這篇文章主要為大家介紹了Go語(yǔ)言開(kāi)發(fā)瀏覽器視頻流rtsp轉(zhuǎn)webrtc播放的過(guò)程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-04-04
  • Go?io/fs.FileMode文件系統(tǒng)基本操作和權(quán)限管理深入理解

    Go?io/fs.FileMode文件系統(tǒng)基本操作和權(quán)限管理深入理解

    這篇文章主要為大家介紹了Go?io/fs.FileMode文件系統(tǒng)基本操作和權(quán)限管理深入理解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • 淺析Go語(yǔ)言中閉包的使用

    淺析Go語(yǔ)言中閉包的使用

    閉包是一個(gè)函數(shù)和其相關(guān)的引用環(huán)境組合的一個(gè)整體。本文主要為大家介紹一下Go語(yǔ)言中閉包的使用,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Go語(yǔ)言有一定幫助,需要的可以參考一下
    2022-12-12

最新評(píng)論