package main
import "fmt"
func modify(foo []string) {
foo[1] = "c"
fmt.Println("modify foo", foo)
}
func main() {
foo := []string{"a", "b"}
fmt.Println("before foo: ", foo)
modify(foo)
fmt.Println("after foo: ", foo)
}
// before foo: [a b]
// modify foo [a c]
// after foo: [a c]
因為是call by reference
所以會影響foo的值
嘗試用append 改變slice
package main
import "fmt"
func addVal(foo []string) {
foo = append(foo, "c")
fmt.Println("modify foo", foo)
}
func main() {
foo := []string{"a", "b"}
fmt.Println("before foo: ", foo)
addVal(foo)
fmt.Println("after foo: ", foo)
}
// before foo: [a b]
// modify foo [a b c]
// after foo: [a b]
因為append回傳新的value
所以addVal function裡的foo是得到append回傳的value
但外面的foo是不會污染的
但如果要用append 改變外頭foo的值呢
可以如下
package main
import "fmt"
func addVal(foo *[]string) {
*foo = append(*foo, "c")
fmt.Println("modify foo", foo)
}
func main() {
foo := []string{"a", "b"}
fmt.Println("before foo: ", foo)
addVal(&foo)
fmt.Println("after foo: ", foo)
}
會得到結果為
// before foo: [a b]
// modify foo &[a b c]
// after foo: [a b c]
但不建議用此方法,維護程式碼會很複雜,很亂
建議寫法如下
package main
import "fmt"
func addVal(foo []string) []string {
foo = append(foo, "c")
fmt.Println("modify foo", foo)
return foo
}
func main() {
foo := []string{"a", "b"}
fmt.Println("before foo: ", foo)
foo = addVal(foo)
fmt.Println("after foo: ", foo)
}
// before foo: [a b]
// modify foo [a b c]
// after foo: [a b c]
這樣閱讀性提高
package main
import "fmt"
func main() {
foo := []string{"a", "b"}
bar := foo[:1]
fmt.Println("bar: ", bar) // [a]
s1 := append(bar, "c")
fmt.Println("foo: ", foo) // [a c]
fmt.Println("s1: ", s1) // [a c]
s2 := append(bar, "d")
fmt.Println("foo: ", foo) // [a d]
fmt.Println("s2: ", s2) // [a d]
s3 := append(bar, "e", "f")
fmt.Println("foo: ", foo) // [a d] 因為超過自己原本是兩個值的空間 =>foo := []string{"a", "b"}
fmt.Println("s3: ", s3) // [a e f]
}