<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Go愛好者周刊 87、88期題解

          共 4433字,需瀏覽 9分鐘

           ·

          2021-04-06 19:41

          閱讀本文大概需要 5 分鐘。

          大家好,我是站長 polarisxu。

          我在 Go 語言愛好者周刊第 8788 期刊首出了兩道題,這兩道題有點類似,都是和切片初始化有關(guān)。但這兩道的題正確率比較低,特別是 88 期的題。

          第 87 期題目如下:

          package main

          import (
           "fmt"
          )

          func main() {
           a := []int{21}
           fmt.Println(a)
          }

          正確答案是:C,正確率 52%。這道題相對簡單,但依然有近一半的人答錯了。

          第 88 期題目和 87 期類似,但難度高一些,題目如下:

          package main

          func main() {
           var x = []int{444556617788}
           println(len(x), x[2])
          }

          正確答案是:C,正確率很低,只有 25%。

          為了更全面,我們講解下 array/slice 的一些相關(guān)知識。

          01 數(shù)組和切片

          關(guān)于兩者,Go 語言規(guī)范中都有明確定義。

          數(shù)組[1]是這么說明的:

          數(shù)組是單一類型元素的有序序列,該單一類型稱為元素類型。元素的個數(shù)被稱為數(shù)組長度,并且不能為負值。長度是數(shù)組類型的一部分;它必須為一個可以被 int 類型的值所代表的非負常量。

          這里一個關(guān)鍵點就是,長度是數(shù)組的一部分,因此 [3]int 和 [4]int 是不同類型。

          再看看切片[2]

          切片是針對一個底層數(shù)組的連續(xù)段的描述符,它提供了對該數(shù)組內(nèi)有序序列元素的訪問。切片類型表示其元素類型的數(shù)組的所有切片的集合。元素的數(shù)量被稱為切片長度,且不能為負。未初始化的切片的值為 nil 。

          從 EBNF 的表示可以看出區(qū)別:

          ArrayType   = "[", ArrayLength, "]", ElementType .
          SliceType = "[""]", ElementType .

          也就是說,長度不是切片類型的一部分,切片長度可變。

          02 常見字面量初始化

          我不打算講解數(shù)組/切片初始化的各種情況,主要介紹常見的字面量初始化,以及和上面題目相關(guān)的部分。

          通常我們會這么初始化一個數(shù)組:

          var intSet = [6]int{246}

          注意 [] 中的 6,它表示數(shù)組的長度。因為初始化時,我們只給定了 3 個數(shù),因此后 3 個元素是 0:

          [2 4 6 0 0 0]

          注意和這種寫法的區(qū)別:

          var intSet = [...]int{246}

          對于切片來說,一般這樣初始化:

          var intSlice = []int{246}

          // 或基于 intSet 進行初始化
          var intSlice = intSet[:]

          當(dāng)然,針對 Slice,更多時候是通過 make 創(chuàng)建,然后其他方式初始化,這里不展開了。

          03 特殊的初始化

          在 Go語言規(guī)范「Composite literals[3]」部分對數(shù)組和切片的字面值初始化進行了規(guī)定,因為數(shù)組和切片類似,我們這里只說切片的情況。

          先看組合字面值的 EBNF 表示:

          CompositeLit  = LiteralType, LiteralValue .
          LiteralType   = StructType | ArrayType | "[""...""]", ElementType |
                          SliceType | MapType | TypeName .
          LiteralValue  = "{", [ ElementList, [ "," ] ], "}" .
          ElementList   = KeyedElement, { ",", KeyedElement } .
          KeyedElement  = [ Key, ":" ], Element .
          Key           = FieldName | Expression | LiteralValue .
          FieldName     = identifier .
          Element       = Expression | LiteralValue .

          從上到下看,簡單解釋一下:

          • 第 1 行,表示組合字面值由 LiteralType 和 LiteralValue 構(gòu)成,其中 LiteralType 表示組合字面值的類型,LiteralValue 表示值;
          • 第 2 行,解釋 LiteralType,它可以是 = 后面的類型。允許的類型有:結(jié)構(gòu)體、數(shù)組、切片、map 等,其中還可以是類似 […]int 的形式;
          • 第 4 行,解釋 LiteralValue,它由一對 {} 包裹,其中包含可選的 ElementList;
          • 第 5 行,解釋 ElementList,它由若干 KeyedElement 組成;
          • 第 6 行,解釋 KeyedElement,這是該篇題目的重點之處。在 EBNF 中,[] 表示這部分是可選的,因此表示具體元素時,一般 Key 可以省略(map 不能省略),這就是通常數(shù)組和切片的初始化語法;

          在這個之后,規(guī)范上給出了針對數(shù)組和切片字面值的應(yīng)用規(guī)則:

          1. 數(shù)組中的每個元素有一個關(guān)聯(lián)的標(biāo)記其位置的整數(shù)索引。
          2. 帶鍵的元素使用該鍵作為其索引。這個鍵必須是可被類型 int 所表示的一個非負常量;而且如果其被賦予了類型的話則必須是整數(shù)類型。
          3. 不帶鍵的元素使用之前元素的索引加一。如果第一個元素沒有鍵,則其索引為零。

          根據(jù)以上 3 點,我們很容易知道,在 a := []int{2: 1} 中,我們指定了第 3 個元素(注意索引是從 0 開始的)的值為 1,根據(jù)數(shù)組/切片的特性,自然存在第 1、2 個元素,沒有指定值時,Go 會為其設(shè)置默認值。因此這個寫法和下面的寫法等價:

          a := []int{001}

          對于第 88 期的題目:

          var x = []int{444556617788}

          指定了第 5 個元素(對應(yīng)索引是 4),值是 44。根據(jù)上面規(guī)則的第三點,55、66 都沒有指定索引,因此它們的索引是前一個元素的索引加一,即:

          555666

          下一個元素是 1: 77,為其指定了索引 1,因此它的下一元素 88 的索引就是 2 了,因此這個定義相當(dāng)于如下的定義:

          var x = []int{444555666177288}

          同樣,因為數(shù)組/切片的特性,缺少的元素(索引 0 和 3)值是 0,而整個切片的長度是最大索引加一,即 7。

          04 總結(jié)

          別覺得這道題目惡心,實際中這么寫代碼可能也確實會被打(當(dāng)然,第 87 題的寫法還是很有可能的)。這里主要是希望大家多掌握一些規(guī)范、細節(jié),我想不少人不清楚,原來數(shù)組(切片)也可以指定索引進行初始化。語言語法畢竟必須嚴謹,而這些都在 Go 語言規(guī)范里。

          延伸思考:第 88 期的題目,如果改為這樣結(jié)果又如何?

          var x = []int{444556637788}

          歡迎大膽的留言說出你的答案!

          參考資料

          [1]

          數(shù)組: https://hao.studygolang.com/golang_spec.html#ruby-rb-rb-rp-rp-rt-array-types-rt-rp-rp-ruby

          [2]

          切片: https://hao.studygolang.com/golang_spec.html#ruby-rb-rb-rp-rp-rt-slice-types-rt-rp-rp-ruby

          [3]

          Composite literals: https://hao.studygolang.com/golang_spec.html#ruby-rb-rb-rp-rp-rt-composite-literals-rt-rp-rp-ruby




          往期推薦


          福利

          我為大家整理了一份從入門到進階的Go學(xué)習(xí)資料禮包,包含學(xué)習(xí)建議:入門看什么,進階看什么。關(guān)注公眾號 「polarisxu」,回復(fù) ebook 獲?。贿€可以回復(fù)「進群」,和數(shù)萬 Gopher 交流學(xué)習(xí)。

          瀏覽 30
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美黑人操逼网 | 97人妻一区二区三区 | 丁香五月天婷婷激情 | 色色五月天丁香社区 | 无码高清视频, |