Golang Go语言中一个初始化 slice 的问题

问一个初始化 slice 的问题,
之前初学 golang 的时候,我经常用下面这种方式来使用 slice:
source := []int{1,2,3,4,5}
res := make([]int, 0)
for _,v := range source {
res = append(res, v)
}
后来了解了 slice 的相关源码之后,发现上面这种写法会导致 slice 多次扩容,便将代码优化成了这种:
source := []int{1,2,3,4,5}
res := make([]int, len(source))
for k,v := range source {
res[k] = v
}
但是遇到一个问题,就是有的时候 source 里面的内容不是我想要的,需要对 v 或者 k 做判断再赋值,如果不符合要求就 continue ,用上面这种方案就会导致 res 部分 index 下是默认的空值 0 。
发现这一情况之后,又改成了下面这种形式:
source := []int{1,2,3,4,5}
res := make([]int, 0, len(source))
for k,v := range source {
if condition {
res = append(res, v)
}
}
因为初始化的时候设置了 cap 字段,这种方案不会像第一个方案那样发生扩容,目前是我想到的最优解了,我想问这种场景下这种 slice 的初始化是最优方案了吗?
Golang Go语言中一个初始化 slice 的问题


更多关于Golang Go语言中一个初始化 slice 的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

9 回复

看起来最后一种没啥毛病了。
另外这点开销大部分情况下你都不用关心…

更多关于Golang Go语言中一个初始化 slice 的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


确实是这样,性能影响非常有限,我也是自己去思考,总结一下,这玩意面试的时候有的时候爱问,思考完理解透了面试就不慌

一般就是你最后那种写法.

没有银弹。假如你的 source 有 100 万个元素但过滤完只有 10 个指定 capacity 就比较浪费了。或者如果 source 没有用你甚至可以直接写回 source 里不用 make 一个新 slice

先瞎 j8 写,有性能问题再改,花里胡哨,什么网站的流量需要考虑这些鬼东西

如果能预估最大容量,就是第 3 种写法。

go 的 slice 和 java 的 ArrayList 差不多,就是我们在数据结构与算法里面学到的基于数组实现的列表,基本的扩容策略是双倍扩容:每次 cap*2 ,摊还每次插入 O(1)。

所以第三种写法是在使用数组实现的列表时的常识,与具体语言无关。

纯复制的时候我喜欢直接

copy()

当然,以下是对关于Golang中初始化slice问题的专业回复:

在Golang中,slice的初始化是一个常见的操作,它提供了灵活且高效的方式来处理动态数组。以下是几种常见的slice初始化方法:

  1. 使用make函数make函数用于分配并初始化一个slice。它接受三个参数:slice的长度、容量(可选,默认为长度)以及元素的类型。例如:

    s := make([]int, 5) // 创建一个长度为5,容量为5的int slice
    
  2. 使用字面量: 你可以直接使用字面量来初始化slice,这种方法适用于已知slice的初始值。例如:

    s := []int{1, 2, 3} // 创建一个包含1, 2, 3的int slice
    
  3. 从数组创建slice: slice可以从数组中获取,通过指定数组的开始和结束索引(半开区间)。例如:

    arr := [5]int{1, 2, 3, 4, 5}
    s := arr[1:4] // 创建一个包含2, 3, 4的slice
    
  4. 使用nil初始化: 一个未初始化的slice其值为nil,你可以直接声明一个slice变量而不分配内存:

    var s []int // s是一个nil slice
    

选择哪种初始化方法取决于你的具体需求,比如是否需要预先分配内存、是否已知初始值等。理解这些初始化方法将帮助你更有效地使用Go中的slice。

回到顶部