Go語言的指針 & *


Go語言保留着C中值和指針的區別,但是對於指針繁瑣用法進行了大量的簡化,引入引用的概念。所以在Go語言中,你幾乎不用擔心會因為直接操作內寸而引起各式各樣的錯誤。Go語言的指針,基本上只剩下用於區分 byref 和 byval 語義。

運算符就是簡單的 & 和 * 一個取地址、一個解析地址。

 
package main
 
import(
    "fmt"
)
 
func main(){
    var i int // i 的類型是int型
    i=1 // i 的值為 1;
    var p *int // p 的類型是[int型的指針]
    p=&i         // p 的值為 [i的地址]
 
    fmt.Printf("i=%d;p=%d;*p=%d\n",i,p,*p)
 
    *p=2 // *p 的值為 [[i的地址]的指針] (其實就是i嘛),這行代碼也就等價於 i = 2
    fmt.Printf("i=%d;p=%d;*p=%d\n",i,p,*p)
 
    i=3 // 驗證想法
    fmt.Printf("i=%d;p=%d;*p=%d\n",i,p,*p)
}
這段代碼執行結果:

i=1;p=0x4212f100;*p=1

i=2;p=0x4212f100;*p=2

i=3;p=0x4212f100;*p=3

函數的參數傳遞可以看下面例子:
 
 
 
 
         package main
 
import "fmt"
 
type abc struct{
    v int
}
 
func (a abc)aaaa(){ //傳入的是值,而不是引用
    a.v=1
    fmt.Printf("1:%d\n",a.v)
}
 
func (a *abc)bbbb(){ //傳入的是引用,而不是值
    fmt.Printf("2:%d\n",a.v)
    a.v=2
    fmt.Printf("3:%d\n",a.v)
}
 
func (a *abc)cccc(){ //傳入的是引用,而不是值
    fmt.Printf("4:%d\n",a.v)
}
 
func main(){
    aobj:=abc{}  //new(abc);
    aobj.aaaa()
    aobj.bbbb()
    aobj.cccc()
}
輸出結果:
 
 
 
         

1:1

2:0

3:2

4:2

傳值與傳指針
當我們傳一個參數值到被調用函數里面時,實際上是傳了這個值的一份copy,當在被調用函數中修改參數值的時候,調用函數中相應實參不會發生任何變化,因為數值變化只作用在copy上。

傳指針比較輕量級 (8bytes),只是傳內存地址,我們可以用指針傳遞體積大的結構體。如果用參數值傳遞的話, 在每次copy上面就會花費相對較多的系統開銷(內存和時間)。所以當你要傳遞大的結構體的時候,用指針是一個明智的選擇。

Go語言中string,slice,map這三種類型的實現機制類似指針,所以可以直接傳遞,而不用取地址后傳遞指針。(注:若函數需改變slice的長度,則仍需要取地址傳遞指針)

要訪問指針 p 指向的結構體中某個元素 x,不需要顯式地使用 * 運算,可以直接 p.x ;

 

一個稍微復雜的例子
 
 
 
 
         package main
 
import "fmt"
 
type S map[string][]string
 
func Summary(paramstring)(s*S){
    s=&S{
        "name":[]string{param},
        "profession":[]string{"Javaprogrammer","ProjectManager"},
        "interest(lang)":[]string{"Clojure","Python","Go"},
        "focus(project)":[]string{"UE","AgileMethodology","SoftwareEngineering"},
        "hobby(life)":[]string{"Basketball","Movies","Travel"},
    }
    return s
}
 
func main(){
    s:=Summary("Harry")
    fmt.Printf("Summary(address):%v\r\n",s)
    fmt.Printf("Summary(content):%v\r\n",*s)
}

 
輸出:
Summary(address): 0x42131100

Summary(content): map[profession:[Java programmer Project Manager] interest(lang):[Clojure Python Go] hobby(life):[Basketball Movies Travel] name:[Harry] focus(project):[UE Agile Methodology Software Engineering]]

exit code 0, process exited normally.


 

參考資料:

使用Go語言一段時間的感受
http://blog.jobbole.com/14386/

[Go 語言] 指針,地址,形參,實參
http://my.oschina.net/nalan/blog/77373

從例子中學習 go 語言 —— 數據結構、指針
http://ilovers.sinaapp.com/drupal/node/33

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM