網(wǎng)站首頁 編程語言 正文
一、前言
??????最近在項(xiàng)目代碼中,發(fā)現(xiàn)了一種寫法,如下所示:
//期望是能把id順序?qū)懙角衅亚衅紳M,元素?cái)?shù)為10個(gè)
Ids1 := make([]int64, 10)
for _, v := range xxxx {
Ids1 = append(Ids1, v.ids1)
}
??????看起來還可以,提前給切片分配長度,防止append
頻繁擴(kuò)容。然而在實(shí)際使用中才發(fā)現(xiàn),以上結(jié)果打印如下:
Ids1:([0 0 0 0 0 0 0 0 0 0 393 394 395 396 397 398 399 400 401 402])
??????是不是跟想象中不一樣,這特么的不是說好的分配長度,使用已有長度,怎么打印出來的是0
,而且切片依然發(fā)生了擴(kuò)容。
二、切片分配長度的正確用法
1、切片的初始化
??????博主百思不得其解,于是去百度切片的用法,發(fā)現(xiàn)一般初始化切片如下:
make([]T, len) //省略cap,len=cap
make([]T, len, cap) // 等價(jià)于 make([]T, cap)[:len]
使用make
初始化,由于未賦值系統(tǒng)默認(rèn)將元素值置為0,即:
數(shù)值類型數(shù)組: 默認(rèn)值為0
字符串?dāng)?shù)組: 默認(rèn)值為""
bool數(shù)組: 默認(rèn)值為false
那么我們打印出來的0
值,是否就是被make初始化零值的原因呢?
2、打印切片長度和容量
Ids1 := make([]int64, 10)
fmt.Println("Ids1切片長度:", len(Ids1))
fmt.Println("Ids1切片容量:", cap(Ids1))
fmt.Println("Ids1切片內(nèi)容:", Ids1)
Ids2 := make([]int64, 0, 10)
fmt.Println("Ids2切片長度:", len(Ids2))
fmt.Println("Ids2切片容量:", cap(Ids2))
fmt.Println("Ids2切片內(nèi)容:", Ids2)
結(jié)果如下:
Ids1切片長度: 10
Ids1切片容量: 10
Ids1切片內(nèi)容: [0 0 0 0 0 0 0 0 0 0]
Ids2切片長度: 0
Ids2切片容量: 10
Ids2切片內(nèi)容: []
??????通過打印結(jié)果我們發(fā)現(xiàn),第一種初始化的方式,同時(shí)定義了len
和cap
,導(dǎo)致切片默認(rèn)分配了零值,當(dāng)我們使用append
的時(shí)候,由于新元素超過了cap(10)
,因此就發(fā)生了擴(kuò)容,導(dǎo)致寫入的元素堆到了后面。
??????第二種初始化的方式,我們定義了cap
,但是len=0
,這樣就不會(huì)默認(rèn)給元素賦零值,因?yàn)榍衅瑢?shí)際上是沒有任何元素的。此時(shí)append
就可以把元素加進(jìn)去,填充切片。
3、正確的用法
(1)下標(biāo)指定
Ids1 := make([]int64, 10)
for k, v := range xxxx {
Ids1[k] = v.ids1
}
(2) 使用另一種初始化方式
Ids1 := make([]int64, 10)
Ids2 := make([]int64, 0, 10)
for _, v := range xxxx {
Ids1 = append(Ids1, v.ids1)
Ids2 = append(Ids2, v.ids2)
}
//打印結(jié)果如下:
Ids1:([0 0 0 0 0 0 0 0 0 0 393 394 395 396 397 398 399 400 401 402])
Ids2:([183 184 184 185 185 186 187 188 189 190])
??????看似簡單的代碼,實(shí)際上也暗藏玄機(jī)。博主一開始也被誤導(dǎo)了,代碼看似提前分配了容量,實(shí)際上沒鳥用,擴(kuò)容跑不了,而且前10
個(gè)元素為0
,這個(gè)時(shí)候萬一靠下標(biāo)獲取元素,直接出bug
沒商量。
end
原文鏈接:https://blog.csdn.net/LJFPHP/article/details/125826204
相關(guān)推薦
- 2023-07-09 Golang syncMap 詳解
- 2022-12-26 使用python如何對(duì)圖片進(jìn)行壓縮_python
- 2022-11-18 React中用@符號(hào)編寫文件路徑實(shí)現(xiàn)方法介紹_React
- 2022-07-20 Flutter系統(tǒng)網(wǎng)絡(luò)圖片加載流程解析_Android
- 2022-08-15 ArrayList和LinkedList和Vector的區(qū)別
- 2022-07-04 C#實(shí)現(xiàn)進(jìn)制轉(zhuǎn)換_C#教程
- 2022-10-24 centos編譯安裝mariadb的詳細(xì)過程_mariadb
- 2022-07-20 python鼠標(biāo)繪圖附代碼_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支