简体   繁体   English

Go 中这两种“切片复制”方法有什么区别

[英]What is a difference between these two “slice copy” approaches in Go

So, why are they (No.1 & No.2 below) different?那么,为什么它们(下面的 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 <<<
}

They ARE different, for sure: No.2 is quite "shallow".它们肯定不同的:No.2 相当“浅”。

When one change t.local[i] , she will garble the original string if No.2 was in use.当更改t.local[i]时,如果使用 2 号,她会将原始字符串乱码。

Your "No.1" approach appends to a nil slice which guarantees that a new backing array will be allocated if there are more than zero params provided.您的“No.1”方法附加到一个nil切片,它保证如果提供的参数超过零,则将分配一个新的支持数组。

Your "No.2" approach doesn't create a new slice, it just slices the param.您的“No.2”方法不会创建新切片,它只是切片参数。

If Assign() is called by passing an existing slice, the 2nd approach will store that, and if its elements are modified, it will be reflected in the stored slice.如果通过传递现有切片调用Assign() ,则第二种方法将存储该切片,如果其元素被修改,它将反映在存储的切片中。

Let's modify your example a little to test it:让我们稍微修改一下您的示例以对其进行测试:

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 <<<
}

Testing it:测试它:

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)

Output (try it on the Go Playground ): Output(在Go Playground上尝试):

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

As you can see, when using Assing1() , the local slice is not affected by modifying the passed slice.如您所见,当使用Assing1()时, local切片不受修改传递的切片的影响。

When using Assing2() , elements of the local slice reflect the changes made in the original.使用Assing2()时, local切片的元素会反映原始切片中所做的更改。

Please read relevant blog posts:请阅读相关博文:

The Go Blog: Go Slices: usage and internals Go 博客:Go 切片:用法和内部结构

The Go Blog: Arrays, slices (and strings): The mechanics of 'append' Go 博客:Arrays,切片(和字符串):“附加”的机制

So, why are they (No.1 & No.2 below) different?那么,为什么它们(下面的 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 <<<
}

They ARE different, for sure: No.2 is quite "shallow".它们肯定不同的:No.2 相当“浅”。

When one change t.local[i] , she will garble the original string if No.2 was in use.当更改t.local[i]时,如果使用 2 号,她会将原始字符串乱码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM