1. 程式人生 > 實用技巧 >Golang中的值拷貝與引用拷貝

Golang中的值拷貝與引用拷貝

變數間的賦值(值拷貝)

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