Go语言 如何公开具有不变性的切片成员?

xkrw2x1b  于 2022-12-07  发布在  Go
关注(0)|答案(1)|浏览(112)

我有一个带切片成员的结构体,以及一个公开这个切片的方法。但是我不希望调用者能够改变切片的内容。如果我这样做:

type A struct {
    slice []int
}

func (a *A) list() []int {
    return a.slice
}

它是不安全的,因为内容很容易被修改:

a := A{[]int{1, 2, 3}}
_ = append(a.list()[:2], 4)
fmt.Println(a.list()) // [1 2 4]

显然,我可以让list()返回切片的副本来避免这种情况:

func (a *A) list() []int {
    return append([]int{}, a.slice...)
}

但这意味着每次当我只想遍历切片时,我都创建了一个副本,这看起来很浪费。2有没有一种方法可以做到这一点而不需要不必要的复制呢?

6ie5vjzr

6ie5vjzr1#

一旦通过返回将这个切片提供给外部调用者,它就可以被修改。如果由于性能原因不能接受复制,可以实现一个访问者:

func (a *A) Visit(f func(int)) {
    for _, v := range a.slice {
        f(v)
    }
}

这根本不公开切片,并允许客户端代码一次性查看切片中的所有项。如果项不是指针或其他可变类型,则这实际上是只读的,因为访问者回调将接收值的副本。
或者,访问者可以返回一个布尔值,以防您希望提前停止迭代。

func (a *A) Visit(f func(int) bool) {
    for _, v := range a.slice {
        if !f(v) {
            return
        }
    }
}

相关问题