<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                >[info] 原文地址: https://blog.golang.org/gos-declaration-syntax **介紹** Go的入門者會疑惑為什么聲明語法和傳統C家族的語法不一樣。本文我們會比較這2種方式,并且解釋為什么Go會這樣聲明。 **C語法** 首先,我們說說C語法。C在聲明語法上用了一個不同尋常很聰明的做法。并沒有使用特殊語法來描述類型,而是編寫一個包含已被聲明項的表達式,并說明這個表達式將具有什么類型。因此 ~~~ int x; ~~~ 聲明x為int類型:表達式'x'將會具有int類型。一般來說,為了弄明白如何書寫一個新變量的類型,就要編寫一個包含該變量的表達式,假如其求值為基本類型,那就把基本類型放在左邊,表達式放在右邊。 如下,聲明如: ~~~ int *p; int a[3]; ~~~ 表明p是一個指向int類型的指針,因為'\*p'具有類型int;并且a是一個int數組,因為a[3](忽略掉這個索引值,只是為了說明數組長度為3)具有int類型。 那么方法該如何聲明類型呢?原本,C的方法聲明在括號外面書寫參數類型,就像這樣: ~~~ int main(argc, argv) int argc; char *argv[]; { /* ... */ } ~~~ 這里,我們再一次看到main是一個方法,因為表達式main(argc, argv)返回了一個int。而在現代記法中,我們這樣寫: ~~~ int main(int argc, char *argv[]) { /* ... */ } ~~~ 但是基本結構是一樣的。 這是一種聰明的句法處理方式,對于簡單類型它表現的很好,但是很快便會讓人困惑。著名的例子是聲明一個方法指針。根據以上原則你會得到如下表達式: ~~~ int (*fp)(int a, int b); ~~~ 這里,fp是一個指向方法的指針,因為如果你寫了表達式(\*fp)(a, b),你將調用一個方法返回int。那如果fp的其中一個參數本身就是一個方法呢? ~~~ int (*fp)(int (*ff)(int x, int y), int b) ~~~ 這里就開始難以閱讀了。 當然了,我們在聲明一個方法時,我們可以不寫參數的名字,因此main可以被聲明為: ~~~ int main(int, char *[]) ~~~ 回憶起argv被這樣聲明: ~~~ char *argv[] ~~~ 所以你從構建類型聲明的正中間去除掉了這個名字。然而這種做法并不很明白,即你通過把名字放在中間,來聲明一個char \*[]類型的東西。 再來看看如果你不命名參數,fp的聲明會變成什么樣子: ~~~ int (*fp)(int (*)(int, int), int) ~~~ 這不僅是不清楚應該把名字放在哪里 ~~~ int (*)(int, int) ~~~ 甚至并不清楚這是一個方法指針的聲明。并且如果返回類型是一個方法指針呢,事情將會更加糟糕: ~~~ int (*(*fp)(int (*)(int, int), int))(int, int) ~~~ 這個甚至很難看出是對fp的聲明表達式。 你還可以構建出更加復雜的例子,但上面這些應該能夠說明C的聲明語法會引入的一些困難。 此外,還有一點需要重點說明。因為類型和聲明語法是一樣的,所以在編譯的中間過程,分析帶有類型的表達式就會變得困難。這就是為什么,比如,C的強制類型轉換總是需要將類型用括號括起來,例如: ~~~ (int)M_PI ~~~ **Go語法** C家族以外的語言,在聲明上通常使用另一種類型語法。也算是一個不同點:名稱通常出現在最前面,通常后面跟上一個冒號。因此上面的例子就變成了如下這樣(使用的是一個虛構用來說明的語言) ~~~ x: int p: pointer to int a: array[3] of int ~~~ 這個聲明很清晰明了,如果遇到冗長的聲明 -- 你只需要從左向右閱讀它們即可領會。Go就從這里吸取了啟發,并且出于簡潔,它丟棄了冒號,并移除了部分關鍵字: ~~~ x int p *int a [3]int ~~~ 在[3]int的書寫方式,和如何在表達式中使用a這兩者之間并沒有直接對應關系。下一節將講述指針。付出分隔語法的代價,你可以清晰的閱讀代碼。 再看看方法。讓我們將main的聲明改寫為Go的方式,雖然Go中真實的main函數不接受參數: ~~~ func main(argc int, argv []string) int ~~~ 表面上看,和C并沒有太多區別,除了char數組變成了string類型,但是它更適合從左往右讀: main方法接收一個int參數,和一個strings片段參數,然后返回一個int。 丟掉參數名字,它同樣清晰 -- 名字總是出現在最前面,所以不會產生困惑。 ~~~ func main(int, []string) int ~~~ 這種從左到右風格的優點是,當類型變得越來越復雜時,它表現的也如此之好。下面是一個方法變量的聲明(類似于C中的方法指針): ~~~ f func(func(int,int) int, int) int ~~~ 或者如果f返回一個方法 ~~~ f func(func(int,int) int, int) func(int, int) int ~~~ 它依然讀起來很清晰,從左向右,因為名字總是出現在最前面,所以整個句子的意思總是顯而易見。 類型和表達式語法之間的區別,使Go編寫和調用閉包很簡單: ~~~ sum := func(a, b int) int { return a+b } (3, 4) ~~~ **指針** 指針是驗證這個規則的例外。留意下數組和片段中,比如,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^ ~~~ 而且很可能我們應該這樣做(同時要給異或運算選一個其它的操作符),因為類型和表達式中的前綴星號都會使事情復雜化。例如,盡管可以這樣進行類型轉換: ~~~ []int("hi")//將其轉換為int數組 ~~~ 但是如果類型前面以\*開始,就必須將其括起來: ~~~ (*int)(nil) ~~~ 假如我們愿意放棄\*作為指針語法,那么這些括號就不是必須的了。 所以Go的指針語法,依賴于熟悉的C形式,但是這種聯系,也意味著我們不能完全打破陳規:使用加括號,來消除類型和表達式在語法上的歧義。 總之,無論怎樣,我們相信Go的類型語法比C的更容易懂,特別是在復雜的情況下。 **備注** Go的聲明閱讀順序是從左到右。而已經有人指出,C的聲明讀法則是螺旋式的。可以參見David Anderson的[The "Clockwise/Spiral Rule"](http://c-faq.com/decl/spiral.anderson.html) 本文由Rob Pike著
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看