从getter方法返回私有切片字段之前,是否应该使用副本?

huangapple go评论81阅读模式
英文:

Should you use copy on private slice fields before returning them from getters?

问题

如果一个struct有一个私有的切片字段,需要使用Getter方法访问,那么在返回之前应该将切片进行复制吗?

我想确认一下是否可以直接从Getter方法中返回私有切片,因为我不希望调用者能够通过Getter方法的返回值修改它们。

根据我目前的测试,返回的切片与私有切片字段没有关联。
然而,我不确定在所有情况下是否都是如此,如果不需要的话,我也不想使用copy

这是我尝试过的代码:

package main

import "fmt"

type Basket struct {
    fruits []string
}

func (b *Basket) Fruits() []string {
    return b.fruits
}

func (b *Basket) AddFruit(fruit string) {
    b.fruits = append(b.fruits, fruit)
}

func main() {
    basket := &Basket{}
    basket.AddFruit("apple")
    basket.AddFruit("banana")
    basket.AddFruit("orange")

    fruits := basket.Fruits()
    fmt.Println(fruits) // [apple banana orange]

    fruits = append(fruits, "mango")
    fruits = append(fruits, "lemon")
    fruits = append(fruits, "pineapple")
    fmt.Println(fruits)          // [apple banana orange mango lemon pineapple]
    fmt.Println(basket.Fruits()) // [apple banana orange]
}

下面是使用copy的Getter方法示例:

func (b *Basket) Fruits() []string {
    result := make([]string, len(b.fruits))
    copy(result, b.fruits)
    return result
}
英文:

If a struct has a private slice field that requires a Getter, should the slice be copied before it gets returned?

I want to confirm if it's safe to return private slices directly from Getters because I don't want callers to be able to modify them through the Getter's return value.

From my testing so far, it seems that returned slices are not linked to the private slice field.
However, I'm not sure if this will be true for all scenarios and I don't want to use copy if it's not needed.

Here's what I tried:

package main

import "fmt"

type Basket struct {
    fruits []string
}

func (b *Basket) Fruits() []string {
    return b.fruits
}

func (b *Basket) AddFruit(fruit string) {
    b.fruits = append(b.fruits, fruit)
}

func main() {
    basket := &Basket{}
    basket.AddFruit("apple")
    basket.AddFruit("banana")
    basket.AddFruit("orange")

    fruits := basket.Fruits()
    fmt.Println(fruits) // [apple banana orange]

    fruits = append(fruits, "mango")
    fruits = append(fruits, "lemon")
    fruits = append(fruits, "pineapple")
    fmt.Println(fruits)          // [apple banana orange mango lemon pineapple]
    fmt.Println(basket.Fruits()) // [apple banana orange]
}

And here's what the Getter would look like with copy:

func (b *Basket) Fruits() []string {
    result := make([]string, len(b.fruits))
    copy(result, b.fruits)
    return result
}

答案1

得分: 0

正如@kostix在评论中提到的,这取决于具体情况。

对于问题中的情况,我们希望使用copy,因为我们希望将Getter的输出与私有字段分开,这样调用者就无法修改它。

英文:

As @kostix mentioned in the comments, it depends on the scenario.

For the one in the OP, we want to use copy since we want to keep the Getter's output separate from the private field so callers can't modify it.

huangapple
  • 本文由 发表于 2023年3月17日 17:41:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/75765981.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定