登录
首页 >  Golang >  Go问答

优化 Go 切片的技巧

来源:stackoverflow

时间:2024-03-03 23:00:25 184浏览 收藏

来到golang学习网的大家,相信都是编程学习爱好者,希望在这里学习Golang相关编程知识。下面本篇文章就来带大家聊聊《优化 Go 切片的技巧》,介绍一下,希望对大家的知识积累有所帮助,助力实战开发!

问题内容

当切片传递时,无法确定底层原始数组是否发生变异,或者原始数组的副本是否发生变异

a = [3]int {0, 1, 2}
s = a[:]
s[0] = 10
a[0] == s[0] // true


s = append(s, 3)
s[0] = 20
a[0] == s[0] // false

假设今天我进行了此类处理

a = [3]int {0, 1, 2}
s = some_func(a[:]) // returns slice
process(s) // a is getting mutated because so far some_func hasn't caused the underlying array to be copied

现在和明天

a = [3]int {0, 1, 2}
s = some_func(a[:]) // returns slice, does append operations
process(s) // a is not getting mutated because some_func caused the underlying array to be copied

那么切片的最佳实践是什么?


解决方案


如果一个函数确实就地修改了切片的底层数组,并且承诺总是就地修改底层数组,那么该函数通常应该采用该切片按值参数而不返回更新的切片:1

// mutate() modifies (the backing array of) s in place to achieve $result.
// see below for why it returns an int.
func mutate(s []t) int {
    // code
}

如果函数可能就地修改底层数组,但可能返回使用新数组的切片,则该函数应返回新的切片值,或者采用指向切片的指针:

// replace() operates on a slice of t, but may return a totally new
// slice of t.
func replace(s []t) []t {
    // code
}

当此函数返回时,您应该假设底层数组(如果您拥有它)可能正在使用,也可能没有使用:

func callsreplace() {
    var arr [10]t
    s := replace(arr[:])
    // from here on, do not use variable arr directly as
    // we don't know if it is s's backing array, or not.

    // more code
}

但是 mutate() 承诺就地修改数组。请注意,mutate 通常需要返回实际更新的数组元素的数量:

func callsMutate() {
    var arr [10]T
    n := Mutate(arr[:])
    // now work with arr[0] through arr[n]

    // more code
}

1当然,它可以采用指向数组对象的指针,并就地修改数组,但这不太灵活,因为数组大小随后会被烘焙到类型中。

本篇关于《优化 Go 切片的技巧》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于Golang的相关知识,请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>