golang的slice问题
```
s1 := []int{1, 2, 3, 4}
s2 := []int{-1, -2, -3}

fmt.Println(append(s1[:1], s2...))

fmt.Println(s1)
```
打印的结果：
```
[1 -1 -2 -3]
[1 -1 -2 -3]

```
弄不明白的是：为什么s1的值也变了？
因为append函数并不保障slice是否被修改，也就是说append可能会修改slice，也可能不修改，所以使用append有两个原则：
append函数调用后，应该使用返回值作为结果。
1. append函数调用后，不应该再使用实参传入的slice。
2. 所以使用append函数一般都是`s = append(s,elem1)`这种用法，也就是把结果重新赋值给原来的slice。
|append函数之所以有这个表现，是因为slice的底层存储依赖于底层数组（underlying array），用你的例子来给你说明一下：
你的s1初始化的值是`[]int{1, 2, 3, 4}`，它的len和cap都是4，所以它的底层数组是一个长度为4的数组`[4]int{1,2,3,4}`。
基于slice的特点，`s1[:1]`和s1是共享底层数组的，所以`s1[:1]`这个slice的改变是会影响到underlying array的。

> If it has sufficient capacity, the destination is resliced to accommodate the new elements. If it does not, a new underlying array will be allocated.

append函数在填充elem1,elem2的时候会先判断slice的cap是否能容纳所有追加的值，这个计算方式是从slice的尾部计算的，在你的例子里，slice的尾部是第一个元素，后面的容量恰好可以满足3个元素，所以它不会申请新的底层数组，而会直接使用原有的底层数组作为存储，这也就把原本的底层数组改成了[1 -1 -2 -3],由于s1的存储依赖于这个底层数组，自然也就变成了`[1 -1 -2 -3]`。

如果把你的例子改成`append(s1[:1],1, s2...)`，或者改成`append(s1[1:2], s2...)`,你就会发现s1没有被改变，这是因为容量不能容纳所有追加元素，append会申请一个新的底层数组用来存储，也会返回一个新的slice，这不会影响到原本的底层数组，也就不会影响到原本的slice。

所以使用`s = append(s,elem1)`是一个好习惯，尽量使用这个用法。