当前位置:网站首页>golang中slice切片使用的误区
golang中slice切片使用的误区
2022-07-27 05:12:00 【铁柱同学】
一、前言
最近在项目代码中,发现了一种写法,如下所示:
//期望是能把id顺序写到切片,把切片占满,元素数为10个
Ids1 := make([]int64, 10)
for _, v := range xxxx {
Ids1 = append(Ids1, v.ids1)
}
看起来还可以,提前给切片分配长度,防止append频繁扩容。然而在实际使用中才发现,以上结果打印如下:
Ids1:([0 0 0 0 0 0 0 0 0 0 393 394 395 396 397 398 399 400 401 402])
是不是跟想象中不一样,这特么的不是说好的分配长度,使用已有长度,怎么打印出来的是0,而且切片依然发生了扩容。
二、切片分配长度的正确用法
1、切片的初始化
博主百思不得其解,于是去百度切片的用法,发现一般初始化切片如下:
make([]T, len) //省略cap,len=cap
make([]T, len, cap) // 等价于 make([]T, cap)[:len]
使用make初始化,由于未赋值系统默认将元素值置为0,即:
数值类型数组: 默认值为0
字符串数组: 默认值为""
bool数组: 默认值为false
那么我们打印出来的0值,是否就是被make初始化零值的原因呢?
2、打印切片长度和容量
Ids1 := make([]int64, 10)
fmt.Println("Ids1切片长度:", len(Ids1))
fmt.Println("Ids1切片容量:", cap(Ids1))
fmt.Println("Ids1切片内容:", Ids1)
Ids2 := make([]int64, 0, 10)
fmt.Println("Ids2切片长度:", len(Ids2))
fmt.Println("Ids2切片容量:", cap(Ids2))
fmt.Println("Ids2切片内容:", Ids2)
结果如下:
Ids1切片长度: 10
Ids1切片容量: 10
Ids1切片内容: [0 0 0 0 0 0 0 0 0 0]
Ids2切片长度: 0
Ids2切片容量: 10
Ids2切片内容: []
通过打印结果我们发现,第一种初始化的方式,同时定义了len和cap,导致切片默认分配了零值,当我们使用append的时候,由于新元素超过了cap(10),因此就发生了扩容,导致写入的元素堆到了后面。
第二种初始化的方式,我们定义了cap,但是len=0,这样就不会默认给元素赋零值,因为切片实际上是没有任何元素的。此时append就可以把元素加进去,填充切片。
3、正确的用法
(1)下标指定
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)
}
//打印结果如下:
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])
看似简单的代码,实际上也暗藏玄机。博主一开始也被误导了,代码看似提前分配了容量,实际上没鸟用,扩容跑不了,而且前10个元素为0,这个时候万一靠下标获取元素,直接出bug没商量。
end
边栏推荐
- NFT new opportunity, multimedia NFT aggregation platform okaleido will be launched soon
- Department management of cloud e-office projects
- The main advantage of face brushing payment users is their high degree of intelligence
- 基于PG-Oracle和MySQL的三库通用sql代码开发
- You should negotiate the handling fee before opening a futures account
- 刷脸支付永远不会过时只会不断的变革
- Personal collection code cannot be used for business collection
- 期货开户公司交返怎么申请?
- Dimitra 和 Ocean Protocol 解读农业数据背后的秘密
- MySQL如何执行查询语句
猜你喜欢

The NFT market pattern has not changed. Can okaleido set off a new round of waves?

How to apply for the return of futures account opening company?

Dimitra and ocean protocol interpret the secrets behind agricultural data

Web2.0 giants have deployed VC, and tiger Dao VC may become a shortcut to Web3

Okaleido上线聚变Mining模式,OKA通证当下产出的唯一方式

期货开户公司交返怎么申请?

Fortex方达发布电子交易生态体系 与客户共享共赢

你真的了解 Session 和 Cookie 吗?

What are the conditions and procedures for opening crude oil futures accounts?

NFT new paradigm, okaleido innovation NFT aggregation trading ecosystem
随机推荐
What are Dom and BOM in JS
什么是Alpha和Beta测试?
选择正规的资质好的期货公司开户
Minimum handling charges and margins for futures companies
The NFT market pattern has not changed. Can okaleido set off a new round of waves?
Es time query error - "caused_by": {"type": "illegal_argument_exception", "reason": "failed to parse date field
Sequel Pro下载及使用方法
Web2.0 giants have deployed VC, and tiger Dao VC may become a shortcut to Web3
存储过程试炼2--建立Test表测试不同类型的存储过程
Minio fragment upload lifting fragment size limit - chunk size must be greater than 5242880
Differences among apply, call, and bind in JS
Personal collection code cannot be used for business collection
期货公司的评级和查询详情
How JS determines whether an object belongs to a class
未来刷脸支付是能够占据市场很多的份额
Web3 traffic aggregation platform starfish OS interprets the "p2e" ecosystem of real business
Several ways of element positioning in page layout
AQUANEE将在近期登陆Gate以及BitMart,低位布局的良机
存储过程试炼1--爱的初相识
vscode打造golang开发环境以及golang的debug单元测试