Search code examples
goslice

Concatenate 2 slices in golang


I have 2 slices,

s1 := []int{1, 2, 3, 4, 5}
s2 := []int{3, 4, 5, 6, 7}

I want the resultant

s3 = []int{1, 2, 3, 4, 5, 3, 4, 5, 6, 7}

I am doing something like:

for _, x := range s1 {
        s2 = append(s2, x)
    }

This looks very trivial question but trust me I don't find a one line solution to this. How can we go about this?


Solution

  • This is what the builtin append() function is for: to append values (which may be values of a slice) to the end of another. And the result is the concatenation.

    If you want s3 to be "independent" of s1 and s2, then append s1 to an empty or nil slice, then append s2 to the result:

    s3 := append(append([]int{}, s1...), s2...)
    fmt.Println(s3)
    

    If s3 may use / overlap s1, you can simply append s2 to s1:

    s4 := append(s1, s2...)
    fmt.Println(s4)
    

    Output in both cases (try it on the Go Playground):

    [1 2 3 4 5 3 4 5 6 7]
    

    Note: What this "overlapping" means is that if you append values to s1, if it has enough capacity, no new slice will be allocated, s1 will be resliced to have enough length to accommodate the elements you want to append to it. This may have surprising side-effects if used unwisely, like in this example:

    arr := [...]int{1, 2, 3, 4, 5, 6, 7, 0, 0, 0}
    
    s1 := arr[:5]
    s2 := arr[2:7]
    fmt.Println("s1:", s1, "cap:", cap(s1))
    fmt.Println("s2:", s2)
    
    s3 := append(s1, s2...)
    fmt.Println("s3:", s3)
    
    fmt.Println("s2:", s2)
    

    Output is (try it on the Go Playground):

    s1: [1 2 3 4 5] cap: 10
    s2: [3 4 5 6 7]
    s3: [1 2 3 4 5 3 4 5 6 7]
    s2: [3 4 5 3 4]
    

    What may be surprising here is that when we appended s2 to s1 and stored the result in s3 (which is what we expected), contents (elements) of s2 also changed. The reason for this is that append() saw that s1 has enough capacity to append s2 to it (elements of s2), so it did not create a new array, it just resliced s1 and added elements "in-place". But the area where the additional elements were written is the exact same memory where elements of s2 reside, so elements of s2 also got overwritten.