成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

聊聊Go語言中的數組與切片

開發(fā) 后端
數組是一個由固定長度的特定類型元素組成的序列,一個數組可以由零個或多個元素組成。因為數組的長度是固定的,因此在 Go 語言中很少直接使用數組。

[[410891]]

本文轉載自微信公眾號「架構精進之路」,作者架構精進之路。轉載本文請聯系架構精進之路公眾號。

1. 數組

數組是一個由固定長度的特定類型元素組成的序列,一個數組可以由零個或多個元素組成。因為數組的長度是固定的,因此在 Go 語言中很少直接使用數組。和數組對應的類型是 Slice(切片),它是可以增長和收縮的動態(tài)序列,slice 功能也更靈活。

數組的每個元素可以通過索引下標來訪問,索引下標的范圍是從 0 開始到數組長度減 1 的位置。內置的 len 函數將返回數組中元素的個數。

  1. var a [3]int             // array of 3 integers 
  2. fmt.Println(a[0])        // print the first element 
  3. fmt.Println(a[len(a)-1]) // print the last element, a[2] 

默認情況下,數組的每個元素都被初始化為元素類型對應的零值,對于數字類型來說就是 0。

  1. var q [3]int = [3]int{1, 2, 3} 
  2. var r [3]int = [3]int{1, 2} 
  3. fmt.Println(r[2]) // "0" 

如果在數組的長度位置出現的是“...”省略號,則表示數組的長度是根據初始化值的個數來計算。因此,上面 q 數組的定義可以簡化為:

  1. q := [...]int{1, 2, 3} 
  2. fmt.Printf("%T\n", q) // "[3]int" 

數組的長度是數組類型的一個組成部分,因此[3]int 和[4]int 是兩種不同的數組類型。

數組的長度必須是常量表達式,因為數組的長度需要在編譯階段確定。

  1. q := [3]int{1, 2, 3} 
  2. q = [4]int{1, 2, 3, 4} // compile error: cannot assign [4]int to [3]int 

如果一個數組的元素類型是可以相互比較的,那么數組類型也是可以相互比較的,這時候我們可以直接通過==比較運算符來比較兩個數組,只有當兩個數組的所有元素都是相等的時候數組才是相等的。不相等比較運算符!=遵循同樣的規(guī)則。

  1. a := [2]int{1, 2} 
  2. b := [...]int{1, 2} 
  3. c := [2]int{1, 3} 
  4. fmt.Println(a == b, a == c, b == c) // "true false false" 
  5. d := [3]int{1, 2} 
  6. fmt.Println(a == d) // compile error: cannot compare [2]int == [3]int 

2. 切片(Slice)

Slice(切片)代表變長的序列,序列中每個元素都有相同的類型。一個 slice 類型一般寫作[]T,其中 T 代表 slice 中元素的類型;slice 的語法和數組很像,只是沒有固定長度而已。

一個 slice 是一個輕量級的數據結構,提供了訪問數組子序列(或者全部)元素的功能,而且 slice 的底層確實引用一個數組對象。

一個 slice 由三個部分構成:指針、長度和容量。

  • 指針指向第一個 slice 元素對應的底層數組元素的地址,要注意的是 slice 的第一個元素并不一定就是數組的第一個元素。
  • 長度對應 slice 中元素的數目;
  • 長度不能超過容量,容量一般是從 slice 的開始位置到底層數據的結尾位置。內置的 len 和 cap 函數分別返回 slice 的長度和容量。

表示一年中每個月份名字的字符串數組,還有重疊引用了該數組的兩個 slice。數組這樣定義:

  1. months := [...]string{1: "January", /* ... */, 12: "December"

因此一月份是 months[1],十二月份是 months[12]。

通常,數組的第一個元素從索引 0 開始,但是月份一般是從 1 開始的,因此我們聲明數組時直接跳過第 0 個元素,第 0 個元素會被自動初始化為空字符串。

slice 的切片操作 s[i:j],其中 0 ≤ i≤ j≤ cap(s),用于創(chuàng)建一個新的 slice,引用 s 的從第 i 個元素開始到第 j-1 個元素的子序列。新的 slice 將只有 j-i 個元素。如果 i 位置的索引被省略的話將使用 0 代替,如果 j 位置的索引被省略的話將使用 len(s)代替。因此,months[1:13]切片操作將引用全部有效的月份,和 months[1:]操作等價;months[:]切片操作則是引用整個數組。讓我們分別定義表示第二季度和北方夏天月份的 slice,它們有重疊部分:

  1. Q2 := months[4:7] 
  2. summer := months[6:9] 
  3. fmt.Println(Q2)     // ["April" "May" "June"
  4. fmt.Println(summer) // ["June" "July" "August"

兩個 slice 都包含了六月份。

append 函數

append 函數用于向 slice 追加元素:

  1. var runes []rune 
  2. for _, r := range "Hello, 世界" { 
  3.     runes = append(runes, r) 
  4. fmt.Printf("%q\n", runes) // "['H' 'e' 'l' 'l' 'o' ',' ' ' '世' '界']" 

為了提高內存使用效率,新分配的數組一般略大于保存 x 和 y 所需要的最低大小。通過在每次擴展數組時直接將長度翻倍從而避免了多次內存分配,也確保了添加單個元素操作的平均時間是一個常數時間。這個程序演示了效果:

  1. func main() { 
  2.     var x, y []int 
  3.     for i := 0; i < 10; i++ { 
  4.         y = appendInt(x, i) 
  5.         fmt.Printf("%d cap=%d\t%v\n", i, cap(y), y) 
  6.         x = y 
  7.     } 
  8.  
  9. //每一次容量的變化都會導致重新分配內存和copy操作: 
  10. 0  cap=1    [0] 
  11. 1  cap=2    [0 1] 
  12. 2  cap=4    [0 1 2] 
  13. 3  cap=4    [0 1 2 3] 
  14. 4  cap=8    [0 1 2 3 4] 
  15. 5  cap=8    [0 1 2 3 4 5] 
  16. 6  cap=8    [0 1 2 3 4 5 6] 
  17. 7  cap=8    [0 1 2 3 4 5 6 7] 
  18. 8  cap=16   [0 1 2 3 4 5 6 7 8] 
  19. 9  cap=16   [0 1 2 3 4 5 6 7 8 9] 

讓我們仔細查看 i=3 次的迭代。當時 x 包含了[0 1 2]三個元素,但是容量是 4,因此可以簡單將新的元素添加到末尾,不需要新的內存分配。然后新的 y 的長度和容量都是 4,并且和 x 引用著相同的底層數組,如圖 4.2 所示。

在下一次迭代時 i=4,現在沒有新的空余的空間了,因此 appendInt 函數分配一個容量為 8 的底層數組,將 x 的 4 個元素[0 1 2 3]復制到新空間的開頭,然后添加新的元素 i,新元素的值是 4。新的 y 的長度是 5,容量是 8;后面有 3 個空閑的位置,三次迭代都不需要分配新的空間。當前迭代中,y 和 x 是對應不同底層數組的 view。這次操作如圖 4.3 所示。

內置的 append 函數可能使用比 appendInt 更復雜的內存擴展策略。

因此,通常我們并不知道 append 調用是否導致了內存的重新分配,因此我們也不能確認新的 slice 和原始的 slice 是否引用的是相同的底層數組空間。

同樣,我們不能確認在原先的 slice 上的操作是否會影響到新的 slice。

 

責任編輯:武曉燕 來源: 架構精進之路
相關推薦

2024-05-17 08:47:33

數組切片元素

2023-01-31 08:48:49

Go語言文件

2023-03-29 08:03:53

2021-04-09 10:38:59

Go 語言數組與切片

2022-03-29 08:30:47

指針數組C語言

2022-06-02 13:54:04

Go數組切片

2022-06-22 09:24:30

云原生Go 語言

2024-10-11 15:01:37

Go語言接口

2024-04-07 11:33:02

Go逃逸分析

2021-07-15 23:18:48

Go語言并發(fā)

2023-12-21 07:09:32

Go語言任務

2023-04-03 08:02:16

切片擴容GO

2021-05-12 08:47:54

Go數組切片

2023-12-27 08:12:04

切片Go語言

2023-11-30 08:09:02

Go語言

2022-07-19 12:25:29

Go

2023-07-29 15:03:29

2021-06-08 07:45:44

Go語言優(yōu)化

2021-03-28 20:58:25

Go語言線程

2021-04-29 09:02:44

語言Go 處理
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 一级片av | 99re在线视频免费观看 | 国产精品一区二区三区四区五区 | 久久精品—区二区三区 | 91精品国产色综合久久 | 91精品国产一二三 | 免费在线看黄视频 | 欧美在线免费 | 蜜桃视频在线观看免费视频网站www | 99爱国产| 99国产精品久久久 | 国内毛片毛片毛片毛片 | 天堂一区 | 国产1区 | 欧美极品在线播放 | 国产精品a久久久久 | 久久久国产精品视频 | 91色视频在线观看 | 黑人粗黑大躁护士 | 亚洲精品自拍视频 | 日韩免费高清视频 | 99reav| 在线观看成人av | 欧美一级免费观看 | 中文字幕精品一区二区三区精品 | 成在线人视频免费视频 | 日韩电影一区二区三区 | 久久久久亚洲精品 | 狠狠的干 | 日韩一| 久久久久99| 成人在线视频一区 | 亚洲 中文 欧美 日韩 在线观看 | 国产日韩欧美中文 | 国产超碰人人爽人人做人人爱 | 久久精品视频网站 | 玖玖视频免费 | 国产一二区免费视频 | 亚洲三级免费看 | 欧美一级特黄aaa大片在线观看 | 中文字幕一区二区三区精彩视频 |