简体   繁体   中英

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

So, why are they (No.1 & No.2 below) different?


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".

When one change t.local[i] , she will garble the original string if No.2 was in use.

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.

Your "No.2" approach doesn't create a new slice, it just slices the param.

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.

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 ):

[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.

When using Assing2() , elements of the local slice reflect the changes made in the original.

Please read relevant blog posts:

The Go Blog: Go Slices: usage and internals

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

So, why are they (No.1 & No.2 below) different?


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".

When one change t.local[i] , she will garble the original string if No.2 was in use.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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