欧美阿v视频在线大全_亚洲欧美中文日韩V在线观看_www性欧美日韩欧美91_亚洲欧美日韩久久精品

主頁(yè) > 知識(shí)庫(kù) > 淺談golang slice 切片原理

淺談golang slice 切片原理

熱門標(biāo)簽:汕頭小型外呼系統(tǒng) 濱州自動(dòng)電銷機(jī)器人排名 建造者2地圖標(biāo)注 阿里云ai電話機(jī)器人 釘釘有地圖標(biāo)注功能嗎 鄭州亮點(diǎn)科技用的什么外呼系統(tǒng) 浙江高頻外呼系統(tǒng)多少錢一個(gè)月 黃岡人工智能電銷機(jī)器人哪個(gè)好 惠州電銷防封電話卡

slice介紹

數(shù)組的長(zhǎng)度在定義之后無(wú)法再次修改;數(shù)組是值類型,每次傳遞都將產(chǎn)生一份副本。顯然這種數(shù)據(jù)結(jié)構(gòu)無(wú)法完全滿足開發(fā)者的真實(shí)需求。在初始定義數(shù)組時(shí),我們并不知道需要多大的數(shù)組,因此我們就需要“動(dòng)態(tài)數(shù)組”。在Go里面這種數(shù)據(jù)結(jié)構(gòu)叫slice,slice并不是真正意義上的動(dòng)態(tài)數(shù)組,而是一個(gè)引用類型。slice總是指向一個(gè)底層array,slice的聲明也可以像array一樣,只是不需要長(zhǎng)度,它是可變長(zhǎng)的,可以隨時(shí)往slice里面加數(shù)據(jù)。

初看起來(lái),數(shù)組切片就像一個(gè)指向數(shù)組的指針,實(shí)際上它擁有自己的數(shù)據(jù)結(jié)構(gòu),而不僅僅是個(gè)指針。數(shù)組切片的數(shù)據(jù)結(jié)構(gòu)可以抽象為以下3個(gè)變量:

1.一個(gè)指向原生數(shù)組的指針(point):指向數(shù)組中slice指定的開始位置;
2.?dāng)?shù)組切片中的元素個(gè)數(shù)(len):即slice的長(zhǎng)度;
3.?dāng)?shù)組切片已分配的存儲(chǔ)空間(cap):也就是slice開始位置到數(shù)組的最后位置的長(zhǎng)度。

從底層實(shí)現(xiàn)的角度來(lái)看,數(shù)組切片實(shí)際上仍然使用數(shù)組來(lái)管理元素,基于數(shù)組,數(shù)組切片添加了一系列管理功能,可以隨時(shí)動(dòng)態(tài)擴(kuò)充存放空間,并且可以被隨意傳遞而不會(huì)導(dǎo)致所管理的元素被重復(fù)復(fù)制。

slice聲明

聲明slice時(shí)方括號(hào)[]內(nèi)沒有任何數(shù)據(jù)
聲明一個(gè)元素類型為int的slice
var mySlice []int    聲明兩個(gè)元素類型為byte的slice   

golang 中的 slice 非常強(qiáng)大,讓數(shù)組操作非常方便高效。在開發(fā)中不定長(zhǎng)度表示的數(shù)組全部都是 slice 。但是很多同學(xué)對(duì) slice 的模糊認(rèn)識(shí),造成認(rèn)為golang中的數(shù)組是引用類型,結(jié)果就是在實(shí)際開發(fā)中碰到很多坑,以至于出現(xiàn)一些莫名奇妙的問題,數(shù)組中的數(shù)據(jù)丟失了。

下面我們就開始詳細(xì)理解下 slice ,理解后會(huì)對(duì)開發(fā)出高效的程序非常有幫助。

這個(gè)是 slice 的數(shù)據(jù)結(jié)構(gòu),它很簡(jiǎn)單,一個(gè)指向真實(shí) array 地址的指針 ptr ,slice 的長(zhǎng)度 len 和容量 cap 。

其中 len 和 cap 就是我們?cè)谡{(diào)用 len(slice) 和 cap(slice) 返回的值。

我們來(lái)按照 slice 的數(shù)據(jù)結(jié)構(gòu)定義來(lái)解析出 ptr, len, cap

// 按照上圖定義的數(shù)據(jù)結(jié)構(gòu)
type Slice struct {
  ptr  unsafe.Pointer    // Array pointer
  len  int        // slice length
  cap   int        // slice capacity
}

下面寫一個(gè)完整的程序,嘗試把golang中slice的內(nèi)存區(qū)域轉(zhuǎn)換成我們定義的 Slice 進(jìn)行解析

package main

import (
  "fmt"
  "unsafe"
)

// 按照上圖定義的數(shù)據(jù)結(jié)構(gòu)
type Slice struct {
  ptr unsafe.Pointer // Array pointer
  len int      // slice length
  cap int      // slice capacity
}

// 因?yàn)樾枰羔樣?jì)算,所以需要獲取int的長(zhǎng)度
// 32位 int length = 4
// 64位 int length = 8
var intLen = int(unsafe.Sizeof(int(0)))

func main() {
  s := make([]int, 10, 20)

  // 利用指針讀取 slice memory 的數(shù)據(jù)
  if intLen == 4 { // 32位
    m := *(*[4 + 4*2]byte)(unsafe.Pointer(s))
    fmt.Println("slice memory:", m)
  } else { // 64 位
    m := *(*[8 + 8*2]byte)(unsafe.Pointer(s))
    fmt.Println("slice memory:", m)
  }

  // 把slice轉(zhuǎn)換成自定義的 Slice struct
  slice := (*Slice)(unsafe.Pointer(s))
  fmt.Println("slice struct:", slice)
  fmt.Printf("ptr:%v len:%v cap:%v \n", slice.ptr, slice.len, slice.cap)
  fmt.Printf("golang slice len:%v cap:%v \n", len(s), cap(s))

  s[0] = 0
  s[1] = 1
  s[2] = 2

  // 轉(zhuǎn)成數(shù)組輸出
  arr := *(*[3]int)(unsafe.Pointer(slice.ptr))
  fmt.Println("array values:", arr)

  // 修改 slice 的 len
  slice.len = 15
  fmt.Println("Slice len: ", slice.len)
  fmt.Println("golang slice len: ", len(s))
}

運(yùn)行一下查看結(jié)果

$ go run slice.go

slice memory: [0 64 6 32 200 0 0 0 10 0 0 0 0 0 0 0 20 0 0 0 0 0 0 0]
slice struct: {0xc820064000 10 20}
ptr:0xc820064000 len:10 cap:20
golang slice len:10 cap:20
array values: [0 1 2]
Slice len: 15
golang slice len: 15

看到了,golang slice 的memory內(nèi)容,和自定義的 Slice 的值,還有按照 slice 中的指針指向的內(nèi)存,就是實(shí)際 Array 數(shù)據(jù)。當(dāng)修改了 slice 中的len, len(s) 也變了。

接下來(lái)結(jié)合幾個(gè)例子,了解下slice一些用法

聲明一個(gè)Array通常使用 make ,可以傳入2個(gè)參數(shù),也可傳入3個(gè)參數(shù),第一個(gè)是數(shù)據(jù)類型,第二個(gè)是 len ,第三個(gè)是 cap 。如果不穿入第三個(gè)參數(shù),則 cap=len ,append 可以用來(lái)向數(shù)組末尾追加數(shù)據(jù)。

這是一個(gè) append 的測(cè)試

// 每次cap改變,指向array的ptr就會(huì)變化一次
s := make([]int, 1)

fmt.Printf("len:%d cap: %d array ptr: %v \n", len(s), cap(s), *(*unsafe.Pointer)(unsafe.Pointer(s)))

for i := 0; i  5; i++ {
  s = append(s, i)
  fmt.Printf("len:%d cap: %d array ptr: %v \n", len(s), cap(s), *(*unsafe.Pointer)(unsafe.Pointer(s)))
}

fmt.Println("Array:", s)

運(yùn)行結(jié)果

len:1 cap: 1 array ptr: 0xc8200640f0
len:2 cap: 2 array ptr: 0xc820064110
len:3 cap: 4 array ptr: 0xc8200680c0
len:4 cap: 4 array ptr: 0xc8200680c0
len:5 cap: 8 array ptr: 0xc82006c080
len:6 cap: 8 array ptr: 0xc82006c080
Array: [0 0 1 2 3 4]

看出來(lái)了吧,每次cap改變的時(shí)候指向array內(nèi)存的指針都在變化。當(dāng)在使用 append 的時(shí)候,如果 cap==len 了這個(gè)時(shí)候就會(huì)新開辟一塊更大內(nèi)存,然后把之前的數(shù)據(jù)復(fù)制過去。

實(shí)際go在append的時(shí)候放大cap是有規(guī)律的。在 cap 小于1024的情況下是每次擴(kuò)大到 2 * cap ,當(dāng)大于1024之后就每次擴(kuò)大到 1.25 * cap 。所以上面的測(cè)試中cap變化是 1, 2, 4, 8

在實(shí)際使用中,我們最好事先預(yù)期好一個(gè)cap,這樣在使用append的時(shí)候可以避免反復(fù)重新分配內(nèi)存復(fù)制之前的數(shù)據(jù),減少不必要的性能消耗。

創(chuàng)建切片

s := []int{1, 2, 3, 4, 5}
fmt.Printf("len:%d cap: %d array ptr: %v \n", len(s), cap(s), *(*unsafe.Pointer)(unsafe.Pointer(s)))
fmt.Println("Array:", s)

s1 := s[1:3]
fmt.Printf("len:%d cap: %d array ptr: %v \n", len(s1), cap(s1), *(*unsafe.Pointer)(unsafe.Pointer(s1)))
fmt.Println("Array", s1)

運(yùn)行結(jié)果

len:5 cap: 5 array ptr: 0xc820012210
Array: [1 2 3 4 5]
len:2 cap: 4 array ptr: 0xc820012218
Array [2 3]

在一個(gè)切片基礎(chǔ)上創(chuàng)建新的切片 s1 ,新切片的 ptr 指向的就是 s1[0] 數(shù)據(jù)的內(nèi)存地址。可以看到指針地址 0xc820012210 與 0xc820012218 相差 8byte 正好是一個(gè)int類型長(zhǎng)度,cap也相應(yīng)的變?yōu)?

就寫到這里了,總結(jié)一下,切片的結(jié)構(gòu)是指向數(shù)據(jù)的指針,長(zhǎng)度和容量。復(fù)制切片,或者在切片上創(chuàng)建新切片,切片中的指針都指向相同的數(shù)據(jù)內(nèi)存區(qū)域。

知道了切片原理就可以在開發(fā)中避免出現(xiàn)錯(cuò)誤了,希望這篇博客可以給大家?guī)?lái)幫助。也希望大家多多支持腳本之家。

您可能感興趣的文章:
  • golang常用手冊(cè)之切片(Slice)原理
  • Golang slice切片操作之切片的追加、刪除、插入等
  • 理解Golang中的數(shù)組(array)、切片(slice)和map
  • golang-切片slice的創(chuàng)建方式

標(biāo)簽:瀘州 滄州 昭通 晉中 阿壩 泰安 駐馬店 東營(yíng)

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《淺談golang slice 切片原理》,本文關(guān)鍵詞  淺談,golang,slice,切片,原理,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《淺談golang slice 切片原理》相關(guān)的同類信息!
  • 本頁(yè)收集關(guān)于淺談golang slice 切片原理的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    欧美阿v视频在线大全_亚洲欧美中文日韩V在线观看_www性欧美日韩欧美91_亚洲欧美日韩久久精品
  • <rt id="w000q"><acronym id="w000q"></acronym></rt>
  • <abbr id="w000q"></abbr>
    <rt id="w000q"></rt>
    欧美一区二区久久久| 精品亚洲aⅴ乱码一区二区三区| 国产成人综合视频| 精品日韩在线视频| 精品国产在天天线2019| 青青青爽久久午夜综合久久午夜| 超碰caoprom| 91精品麻豆日日躁夜夜躁| 亚洲一二三区在线观看| 久久久久久国产精品日本| 欧美亚洲尤物久久| 一本一道波多野结衣一区二区| 国产午夜精品久久久久久免费视 | 亚洲成人免费看| 国产免费a级片| 欧美精品在欧美一区二区少妇 | 中文字幕另类日韩欧美亚洲嫩草| 日本一区二区成人在线| 丁香五精品蜜臀久久久久99网站| 成人涩涩小片视频日本| 亚洲品质自拍视频网站| wwwxxx色| 日韩一区二区三区视频| 久久国产婷婷国产香蕉| 日本在线观看网址| 自拍视频在线观看一区二区| 91蜜桃婷婷狠狠久久综合9色| 欧美日韩三级一区| 日本大胆欧美人术艺术动态| 国产1区2区在线观看| 国产精品久久久久久久午夜片| av成人免费在线| 欧美丰满高潮xxxx喷水动漫| 蜜桃久久精品一区二区| 午夜国产福利视频| 亚洲欧美激情小说另类| 亚洲av成人片色在线观看高潮| 精品久久免费看| 国产成人在线电影| 欧美午夜理伦三级在线观看| 奇米777欧美一区二区| 一级片黄色录像| 亚洲柠檬福利资源导航| 99久久久无码国产精品性波多 | 五月婷婷六月香| 日韩理论片网站| 国产大学生视频| 久久影音资源网| 97久久精品人人爽人人爽蜜臀| 5566中文字幕一区二区电影| 精品一区二区三区久久| 日本高清不卡视频| 免费成人在线观看视频| 久久国产美女视频| 午夜电影久久久| 性少妇xx生活| 亚洲大型综合色站| 国产一区二区三区视频播放| 亚洲激情校园春色| 中字幕一区二区三区乱码| 亚洲免费观看高清完整版在线观看熊 | 欧美国产日韩在线观看| 韩国三级与黑人| 2023国产精品| 极品人妻一区二区| 久久久久99精品一区| 永久免费看片在线观看| 中文字幕免费高清| 亚洲黄色免费电影| 国产极品视频在线观看| 亚洲成在线观看| 日本妇女毛茸茸| 蜜桃久久久久久| 欧美午夜不卡视频| 国产成人亚洲综合a∨婷婷| 91精品国产综合久久福利软件| 高清免费成人av| 精品少妇一区二区三区在线视频| 91色porny蝌蚪| 国产日韩欧美亚洲| 国产人妻人伦精品1国产丝袜| 亚洲欧美日韩国产手机在线 | 91精彩刺激对白露脸偷拍| 亚洲欧美日韩国产手机在线| 国产在线综合视频| 日韩在线a电影| 欧美在线你懂得| 国产69精品久久久久毛片| 日韩精品一区二区三区视频在线观看| 99国产精品久久久久久久久久久 | 一级做a爱片久久| 99re6热在线精品视频| 日本不卡在线视频| 欧美日韩一区精品| www.日韩在线| 国产精品久久久久影院色老大| 尤物视频最新网址| 日本va欧美va精品| 欧美日韩在线播| 99久久久免费精品国产一区二区 | 国产成人免费视频网站 | 欧美电视剧在线看免费| 国产一级免费片| 一区二区三区在线视频观看| 亚洲熟女www一区二区三区| 国产一区二区三区免费在线观看| 日韩欧美国产一区二区在线播放 | 亚洲一区 欧美| 久久er99热精品一区二区| 91精品国产一区二区| 久久发布国产伦子伦精品| 亚洲欧美日韩在线| 一本一道波多野结衣一区二区| 国产999精品久久久久久| 国产亚洲精品超碰| 99久久99久久精品免费看小说.| 欧美一区二区三区在线看| 佐佐木明希电影| 亚洲小少妇裸体bbw| 欧美性猛交xxxxxxxx| 91免费版在线| 一区二区三区精品视频| 在线亚洲人成电影网站色www| 99久精品国产| 亚洲精品你懂的| 欧美婷婷六月丁香综合色| 手机在线播放av| 亚洲高清视频在线| 欧美日韩大陆一区二区| youjizz.com国产| 日韩高清在线观看| 精品久久一区二区| 国产精品麻豆一区| 成人av资源下载| 亚洲精品你懂的| 欧美日韩视频不卡| 国产毛片毛片毛片毛片毛片毛片| 日韩av不卡一区二区| 精品福利二区三区| 国产视频精品免费| 成人综合在线视频| 亚洲美女淫视频| 在线播放一区二区三区| 国产偷人妻精品一区| 狠狠色丁香婷婷综合久久片| 亚洲国产成人在线| 一本大道av伊人久久综合| 日本黄色www| 日韩精品久久理论片| 久久先锋影音av鲁色资源网| 免费看特级毛片| 丰满人妻一区二区三区大胸| 午夜精品久久一牛影视| 欧美r级电影在线观看| 强制高潮抽搐sm调教高h| 99久久综合精品| 日韩高清国产一区在线| 久久亚洲一级片| 一本一道久久a久久精品| 制服丝袜av在线| 亚洲精品一区二区精华| 永久免费看mv网站入口| 91麻豆高清视频| 免费精品99久久国产综合精品| 国产午夜精品理论片a级大结局 | 国产大学生视频| 国内成人免费视频| 国产精品色婷婷久久58| 欧美色精品在线视频| 免费污网站在线观看| 成人av第一页| 日韩av成人高清| 国产精品精品国产色婷婷| 欧美精品在线观看播放| jizzjizz日本少妇| 亚洲一二三四五| 国产精品996| 日日摸夜夜添夜夜添亚洲女人| 欧美经典一区二区三区| 精品视频在线免费| 国产视频123区| 丰满人妻一区二区三区53视频| 久国产精品韩国三级视频| 亚洲蜜臀av乱码久久精品蜜桃| 精品日韩在线一区| 91成人免费在线视频| 亚洲精品国产熟女久久久| 91免费国产视频网站| 国产在线乱码一区二区三区| 亚洲一区av在线| 中文字幕乱码久久午夜不卡 | 欧美日韩视频第一区| 日本成人免费在线观看| 少妇被狂c下部羞羞漫画| 粉嫩aⅴ一区二区三区四区五区| 午夜精品久久久久久久99樱桃| 国产日韩v精品一区二区| 欧美精品国产精品| 在线观看xxx| 国产伦精品一区二区三区视频女|