<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在go語言的學習歷程當中,slice資料型別引起了我的好奇心。為啥不直接使用Slice,是人性的扭曲還是道德的淪喪~,下面讓我們一探究竟~~
go語言中的slice是一個基於Array封裝的資料結構,go語言中slice的使用頻率遠高於array,其身影頻頻出現在原始碼實現當中。slice相對於Array的優點就是其可以動態調整自己的size,不像Array的Size是固定的。
slice的建立有兩個方法分別是使用字面量定義和使用make函數。除過slice建立,其他slice的生成辦法均是從現有slice分片或者array上做slice分片操作。
slice建立程式碼:
package main import ( "fmt" "reflect" ) func main() { //字面創造Slice sliceOne := []string{"a", "b"} //使用make函數創造slice sliceTwo := make([]string, 10) sliceThree := make([]int, 10) fmt.Printf("使用字面量建立的slice%sn",reflect.ValueOf(sliceOne).String()) fmt.Printf("使用make函數建立的slice:%sn",reflect.ValueOf(sliceTwo).String()) fmt.Printf("使用make函數建立的slice:%sn",reflect.ValueOf(sliceThree).String()) }
程式輸出:
使用字面量建立的slice<[]string Value>
使用make函數建立的slice:<[]string Value>
使用make函數建立的slice:<[]int Value>
Process finished with the exit code 0
學習過程中,很多小夥伴會對slice的長度和容量問題有著很多混淆。
這個地方可以把切片比喻成一個可以裝10個蘋果的袋子,現在的袋子裡面有三顆蘋果。切片的長度就是袋子已經裝的果子的個數,目前是3個。切片的容量就是這個袋子一共能裝多少個果子,對於這個袋子來說就是10。那麼把程式碼替換成切片,把蘋果替換成元素,是不是就懂了撒~
下面就是該問題的處理辦法就是直接去官方,看原始碼。看看第一手資料怎麼講!
長度:slice中擁有的元素個數,如果slice是nil的話,則元素個數長度是0
英文:the number of elements in v; if v is nil, len(v) is zero
容量:slice切片的長度能夠到達的最大值
英文:Slice: the maximum length the slice can reach when resliced;
程式碼驗證環節:
package main import ( "fmt" ) func main() { sliceOne := []string{"a", "b"} strings := sliceOne[0:1] fmt.Printf("切片的長度:%dn",len(strings)) fmt.Printf("切片的容量:%dn",cap(strings)) }
程式碼結果輸出:
切片的長度:1
切片的容量:2
程式碼原理解析:
strings由sliceOne切片而來,切出來的片上資料有的是0到1,有一個元素,故其對應的長度是1。
因為切片是一個參照型別,只在原始切片上切出了0到1的位置,剩餘的空位還有1,故其容量等於長度加剩餘元素位置數。
slice越界程式碼範例如下:
sliceOne := []string{"a", "b"} //使用make函數創造slice s := sliceOne[2] fmt.Printf(s)
使用sliceOne[2]語句時,陣列越界報錯。
實際開發過程中,總會有slice容量不夠用的時候,該怎麼擴容,如何保證安全擴容?
go語言官方提供的擴容辦法就是建立一個新的更大的分片,將老分片的資料內容遷移到新的切片當中。
程式碼展示:
package main import ( "fmt" ) func main() { sliceOne := []string{"a", "b"} fmt.Printf("切片擴容前") fmt.Printf("切片的長度:%dn",len(sliceOne)) fmt.Printf("切片的容量:%dn",cap(sliceOne)) t := make([]string, len(sliceOne), (cap(sliceOne))*2) copy(t, sliceOne) sliceOne = t fmt.Printf("切片擴容後") fmt.Printf("切片的長度:%dn",len(sliceOne)) fmt.Printf("切片的容量:%dn",cap(sliceOne)) }
結果展示:
切片的長度:2
切片的容量:2
切片的長度:2
切片的容量:4
從程式碼結果上看出新切片的長度是2,容量是4,也再次驗證了切片的長度取決於存放了多少元素,切片的容量取決於已存放的元素數量加剩餘位置數。
舉例
現在需要判斷命令列是否傳了引數,即 os.Args[1] 是否存在
如果使用下述的判斷:
func main() { fmt.Println(os.Args[1]) }
會報錯:index out of range
panic: runtime error: index out of range [1] with length 1
goroutine 1 [running]:
main.main()
D:/go_work/test/test4.go:9 +0xbc
exit status 2
現有兩種方式解決:
第一種:
通過遍歷的方式判斷 key 是否存在
func main() { var result string for k, v := range os.Args { if k == 1 { result = v } } if result != "" { fmt.Printf("os.Args[1] = %s", result) } }
第二種:
由於陣列下標從0開始,len(arr)-1 為最後一個元素的下標,所以判斷所要查詢的 key 是否小於 len(arr) 就可以了
func main() { if len(os.Args)>=2 { fmt.Printf("os.Args[1] = %s", os.Args[1]) } }
go語言中slice的應用和使用相對來說方便快捷很多,不過也有一些小小的暗坑等待大家發現和整理哦~後續我會在我的部落格中,繼續釋出有關於go語言使用的tips和技巧~
到此這篇關於go語言中切片Slice與陣列Array對比以及panic: runtime error: index out of range問題解決的文章就介紹到這了,更多相關go語言切片Slice和陣列Array內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45