Golang中的值拷貝與引用拷貝
阿新 • • 發佈:2020-11-20
變數間的賦值(值拷貝)
a:=1 b:=a fmt.Println(b,&a,&b)
方法呼叫
值拷貝:
1 array
golang中以array作為引數的方法呼叫,方法接收的是整個array的值拷貝,所以方法中對array的item重新賦值不起作用。
如以下程式碼所示,輸出為[1, 2, 3]。
package main import "fmt" func modify(a [3]int) { a[0] = 4 } func main() { a := [3]int{1, 2, 3} modify(a) fmt.Println(a) }
2 struct
如下程式碼傳參為struct值拷貝,modify方法或modify函式對person的name屬性重新賦值不起作用。
package main import "fmt" type person struct { name string } func (p person) modify() { p.name = "jacky" } func modify(p person) { p.name = "jacky" } func main() { p := person{"larry"} p.modify() // modify(p) fmt.Println(p) }
2.引用拷貝
2.1 slice
slice作為底層的陣列引用,方法呼叫採用的是引用的拷貝。
所以,如下第一段程式碼,函式的引用拷貝與原始引用指向同一塊陣列,對slice的item重新賦值是生效的,輸出為[4, 2, 3]。
package main import "fmt" func modify(s []int) { s[0] = 4 } func main() { s := []int{1, 2, 3} modify(s) fmt.Println(s) }
但第二段程式碼,輸出結果未變化,仍為[1, 2, 3]。是因為對引用的拷貝重新賦值,並不會更改原始引用。
package main import "fmt" func modify(s []int) { s = append(s, 4) } func main() { s := []int{1, 2, 3} modify(s) fmt.Println(s) }
所以對slice進行append操作,需要將其作為返回值返回,如以下程式碼所示,輸出為[1 2 3 4]。
package main import "fmt" func modify(s []int) []int { s = append(s, 4) return s } func main() { s := []int{1, 2, 3} s = modify(s) fmt.Println(s) }
2.2 struct pointer
若想改變struct的屬性值,傳參採用struct pointer。
package main import "fmt" type person struct { name string } func (p *person) modify() { p.name = "jacky" } func modify(p *person) { p.name = "jacky" } func main() { p := &person{"larry"} p.modify() // modify(p) fmt.Println(p) }