zoukankan      html  css  js  c++  java
  • 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)  
    }
  • 相关阅读:
    Volatile vs. Interlocked vs. lock
    TransactionScope IsolationLevel 事务隔离级别
    C# LinqAggregate
    .net线程入门1进程
    删除centos更新后多余的内核
    网页中怎么导入css的3方式
    面试常用基础理论(三)
    面试常用基础理论(四)
    Jmeter基本概念
    面试常用基础理论(二)
  • 原文地址:https://www.cnblogs.com/peteremperor/p/14011747.html
Copyright © 2011-2022 走看看