arrays - Go 中这两种 "slice copy"方法有什么区别

标签 arrays go slice

那么,为什么它们(下面的 No.1 和 No.2)不同?


type T1 struct {
    local []string
}

func (t *T1) Assign(param ...string) {
    t.local = nil
    t.local = append(t.local, param...) // No.1 <<<
    t.local = param[:]                  // No.2 <<<
}

当然,它们不同的:No.2 相当“肤浅”。

当更改t.local[i]时,如果使用No.2,她将导致原始字符串出现乱码。

最佳答案

您的“No.1”方法附加到一个 nil slice ,这保证了如果提供的参数超过零,将分配一个新的后备数组。

您的“No.2”方法不会创建新 slice ,它只是对参数进行 slice 。

如果通过传递现有 slice 来调用Assign(),则第二种方法将存储该 slice ,并且如果其元素被修改,它将反射(reflect)在存储的 slice 中。

让我们稍微修改一下您的示例来测试它:

type T1 struct {
    local []string
}

func (t *T1) Assign1(param ...string) {
    t.local = nil
    t.local = append(t.local, param...) // No.1 <<<
}

func (t *T1) Assign2(param ...string) {
    t.local = nil
    t.local = param[:] // No.2 <<<
}

测试它:

t1 := &T1{}

s := []string{"a", "b", "c"}
t1.Assign1(s...)
fmt.Println(t1.local)
s[0] = "x"
fmt.Println(t1.local)

s = []string{"a", "b", "c"}
t1.Assign2(s...)
fmt.Println(t1.local)
s[0] = "x"
fmt.Println(t1.local)

输出(在 Go Playground 上尝试):

[a b c]
[a b c]
[a b c]
[x b c]

如您所见,使用 Assing1() 时,修改传递的 slice 不会影响 local slice 。

使用 Assing2() 时,local slice 的元素反射(reflect)原始 slice 中所做的更改。

请阅读相关博客文章:

The Go Blog: Go Slices: usage and internals

The Go Blog: Arrays, slices (and strings): The mechanics of 'append'

关于arrays - Go 中这两种 "slice copy"方法有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62652960/

相关文章:

javascript - 检查数组中的元素是否连续---javascript

python - 将数组存储为 Pandas 列中的值

arrays - 在 swift 中调用解析函数失败

file - 在golang中发送图像而不下载它

go - log.Flags() 应该与 write 共享相同的 sync.Mutex 吗?

python - 将 a(字符串或整数)划分为 min(长度或值)为 2 的 n 个元素

javascript - 如何在 VueJS 中将循环项推送到数组中

unit-testing - 如何对pubsub进行单元测试接收回调

python - Cython:将单个元素分配给多维内存 View 切片

python - 在大型一维 NumPy 数组中切片模式