<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>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 7.1 聲明和初始化 - [7.1.1 概念](#711__1) - [\[\](https://github.com/Unknwon/the-way-to-go\_ZH\_CN/blob/master/eBook/07.1.md#712-數組常量)7.1.2 數組常量](#httpsgithubcomUnknwonthewaytogo_ZH_CNblobmastereBook071md712712__2) - [\[\](https://github.com/Unknwon/the-way-to-go\_ZH\_CN/blob/master/eBook/07.1.md#713-多維數組)7.1.3 多維數組](#httpsgithubcomUnknwonthewaytogo_ZH_CNblobmastereBook071md713713__3) - [\[\](https://github.com/Unknwon/the-way-to-go\_ZH\_CN/blob/master/eBook/07.1.md#714-將數組傳遞給函數)7.1.4 將數組傳遞給函數](#httpsgithubcomUnknwonthewaytogo_ZH_CNblobmastereBook071md714714__4) ## 7.1.1 概念 數組是具有相同 **唯一類型** 的一組已編號且長度固定的數據項序列(這是一種同構的數據結構);這種類型可以是任意的原始類型例如整形、字符串或者自定義類型。數組長度必須是一個常量表達式,并且必須是一個非負整數。數組長度也是數組類型的一部分,所以\[5\]int和\[10\]int是屬于不同類型的。數組的編譯時值初始化是按照數組順序完成的(如下)。 **注意事項** 如果我們想讓數組元素類型為任意類型的話可以使用空接口作為類型(參考 [第 11 章](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/11.9.md))。當使用值時我們必須先做一個類型判斷(參考 [第 11 章](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/11.3.md))。 數組元素可以通過 **索引**(位置)來讀取(或者修改),索引從 0 開始,第一個元素索引為 0,第二個索引為 1,以此類推。(數組以 0 開始在所有類 C 語言中是相似的)。元素的數目,也稱為長度或者數組大小必須是固定的并且在聲明該數組時就給出(編譯時需要知道數組長度以便分配內存);數組長度最大為 2Gb。 聲明的格式是: ``` var identifier [len]type ``` 例如: ``` var arr1 [5]int ``` 在內存中的結構是:[![](https://box.kancloud.cn/b4d39a40ca2df83c7f170b2e13a08a7f_421x236.)](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/images/7.1_fig7.1.png?raw=true) 每個元素是一個整形值,當聲明數組時所有的元素都會被自動初始化為默認值 0。 arr1 的長度是 5,索引范圍從 0 到 `len(arr1)-1`。 第一個元素是 `arr1[0]`,第三個元素是 `arr1[2]`;總體來說索引 i 代表的元素是 `arr1[i]`,最后一個元素是`arr1[len(arr1)-1]`。 對索引項為 i 的數組元素賦值可以這么操作:`arr[i] = value`,所以數組是 **可變的**。 只有有效的索引可以被使用,當使用等于或者大于 `len(arr1)` 的索引時:如果編譯器可以檢測到,會給出索引超限的提示信息;如果檢測不到的話編譯會通過而運行時會 panic:(參考 [第 13 章](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/13.0.md)) ``` runtime error: index out of range ``` 由于索引的存在,遍歷數組的方法自然就是使用 for 結構: - 通過 for 初始化數組項 - 通過 for 打印數組元素 - 通過 for 依次處理元素 示例 7.1 [for\_arrays.go](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/examples/chapter_7/for_arrays.go) ``` package main import "fmt" func main() { var arr1 [5]int for i:=0; i < len(arr1); i++ { arr1[i] = i * 2 } for i:=0; i < len(arr1); i++ { fmt.Printf("Array at index %d is %d\n", i, arr1[i]) } } ``` 輸出結果: ``` Array at index 0 is 0 Array at index 1 is 2 Array at index 2 is 4 Array at index 3 is 6 Array at index 4 is 8 ``` for 循環中的條件非常重要:`i < len(arr1)`,如果寫成 `i <= len(arr1)` 的話會產生越界錯誤。 IDIOM: ``` for i:=0; i < len(arr1); i++{ arr1[i] = ... } ``` 也可以使用 for-range 的生成方式: IDIOM: ``` for i,_:= range arr1 { ... } ``` 在這里i也是數組的索引。當然這兩種 for 結構對于切片(slices)(參考 [第 7 章](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/07.2.md))來說也同樣適用。 **問題 7.1** 下面代碼段的輸出是什么? ``` a := [...]string{"a", "b", "c", "d"} for i := range a { fmt.Println("Array item", i, "is", a[i]) } ``` Go 語言中的數組是一種 **值類型**(不像 C/C++ 中是指向首元素的指針),所以可以通過 `new()` 來創建: `var arr1 = new([5]int)`。 那么這種方式和 `var arr2 [5]int` 的區別是什么呢?arr1 的類型是 `*[5]int`,而 arr2的類型是 `[5]int`。 這樣的結果就是當把一個數組賦值給另一個時,需要在做一次數組內存的拷貝操作。例如: ``` arr2 := arr1 arr2[2] = 100 ``` 這樣兩個數組就有了不同的值,在賦值后修改 arr2 不會對 arr1 生效。 所以在函數中數組作為參數傳入時,如 `func1(arr2)`,會產生一次數組拷貝,func1 方法不會修改原始的數組 arr2。 如果你想修改原數組,那么 arr2 必須通過&操作符以引用方式傳過來,例如 func1(&arr2),下面是一個例子 示例 7.2 [pointer\_array.go](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/examples/chapter_7/pointer_array.go): ``` package main import "fmt" func f(a [3]int) { fmt.Println(a) } func fp(a *[3]int) { fmt.Println(a) } func main() { var ar [3]int f(ar) // passes a copy of ar fp(&ar) // passes a pointer to ar } ``` 輸出結果: ``` [0 0 0] &[0 0 0] ``` 另一種方法就是生成數組切片并將其傳遞給函數(詳見第 7.1.4 節)。 **練習** 練習7.1:array\_value.go: 證明當數組賦值時,發生了數組內存拷貝。 練習7.2:for\_array.go: 寫一個循環并用下標給數組賦值(從 0 到 15)并且將數組打印在屏幕上。 練習7.3:fibonacci\_array.go: 在第 6.6 節我們看到了一個遞歸計算 Fibonacci 數值的方法。但是通過數組我們可以更快的計算出 Fibonacci 數。完成該方法并打印出前 50 個 Fibonacci 數字。 ## 7.1.2 數組常量 如果數組值已經提前知道了,那么可以通過 **數組常量** 的方法來初始化數組,而不用依次使用 `[]=` 方法(所有的組成元素都有相同的常量語法)。 示例 7.3 [array\_literals.go](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/examples/chapter_7/array_literals.go) ``` package main import "fmt" func main() { // var arrAge = [5]int{18, 20, 15, 22, 16} // var arrLazy = [...]int{5, 6, 7, 8, 22} // var arrLazy = []int{5, 6, 7, 8, 22} var arrKeyValue = [5]string{3: "Chris", 4: "Ron"} // var arrKeyValue = []string{3: "Chris", 4: "Ron"} for i:=0; i < len(arrKeyValue); i++ { fmt.Printf("Person at %d is %s\n", i, arrKeyValue[i]) } } ``` 第一種變化: ``` var arrAge = [5]int{18, 20, 15, 22, 16} ``` 注意 `[5]int` 可以從左邊起開始忽略:`[10]int {1, 2, 3}` :這是一個有 10 個元素的數組,除了前三個元素外其他元素都為 0。 第二種變化: ``` var arrLazy = [...]int{5, 6, 7, 8, 22} ``` `...` 可同樣可以忽略,從技術上說它們其實變化成了切片。 第三種變化:`key: value syntax` ``` var arrKeyValue = [5]string{3: "Chris", 4: "Ron"} ``` 只有索引 3 和 4 被賦予實際的值,其他元素都被設置為空的字符串,所以輸出結果為: ``` Person at 0 is Person at 1 is Person at 2 is Person at 3 is Chris Person at 4 is Ron ``` 在這里數組長度同樣可以寫成 `...` 或者直接忽略。 你可以取任意數組常量的地址來作為指向新實例的指針。 示例 7.4 [pointer\_array2.go](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/examples/chapter_7/pointer_array2.go) ``` package main import "fmt" func fp(a *[3]int) { fmt.Println(a) } func main() { for i := 0; i < 3; i++ { fp(&[3]int{i, i * i, i * i * i}) } } ``` 輸出結果: ``` &[0 0 0] &[1 1 1] &[2 4 8] ``` 幾何點(或者數學向量)是一個使用數組的經典例子。為了簡化代碼通常使用一個別名: ``` type Vector3D [3]float32 var vec Vector3D ``` ## 7.1.3 多維數組 數組通常是一維的,但是可以用來組裝成多維數組,例如:`[3][5]int`,`[2][2][2]float64`。 內部數組總是長度相同的。Go 語言的多維數組是矩形式的(唯一的例外是切片的數組,參見第 7.2.5 節)。 示例 7.5 [multidim\_array.go](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/examples/chapter_7/multidim_array.go) ``` package main const ( WIDTH = 1920 HEIGHT = 1080 ) type pixel int var screen [WIDTH][HEIGHT]pixel func main() { for y := 0; y < HEIGHT; y++ { for x := 0; x < WIDTH; x++ { screen[x][y] = 0 } } } ``` ## 7.1.4 將數組傳遞給函數 把第一個大數組傳遞給函數會消耗很多內存。有兩種方法可以避免這種現象: - 傳遞數組的指針 - 使用數組的切片 接下來的例子闡明了第一種方法: 示例 7.6 [array\_sum.go](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/examples/chapter_7/array_sum.go) ``` package main import "fmt" func main() { array := [3]float64{7.0, 8.5, 9.1} x := Sum(&array) // Note the explicit address-of operator // to pass a pointer to the array fmt.Printf("The sum of the array is: %f", x) } func Sum(a *[3]float64) (sum float64) { for _, v := range a { // derefencing *a to get back to the array is not necessary! sum += v } return } ``` 輸出結果: ``` The sum of the array is: 24.600000 ``` 但這在 Go 中并不常用,通常使用切片(參考 [第 7.2 節](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/07.2.md))。
                  <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>

                              哎呀哎呀视频在线观看