golang學習的點點滴滴:指針,地址,形參,實參

學習Go語言的過程當中,會發現它的指針,地址,還有函數參數跟日常咱們理解的不太同樣.golang


上代碼:函數



package main學習

 

//學習指針用法spa

 

import (指針

    "fmt"orm

)對象

 

func main() {內存

    var i int;          // i 的類型是int型it

    var p *int;             // p 的類型是[int型的指針]import

        i = 1;              // i 的值爲 1;

    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=0x4212e100;*p=1

i=2;p=0x4212e100;*p=2

i=3;p=0x4212e100;*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

能夠看到函數aaaa中,v賦值的1在函數bbbb和cccc裏消失了.爲何呢?

細心的同窗發現aaaa的[接收實體](也就是abc)是一個實參,在go語言中,實參其實就是將參數的值複製到函數裏來(參數與函數調用前在內存裏的地址是不同的).bbbb和cccc的[接收實體]是一個形參,也就是說,函數調用先後參數所在內存地址是同樣的!因此bbbb中,第一行的v還沒賦值因此爲0,第二行的v賦值2之後在cccc中打印v的值也爲2.


 本身的理解 :

    golang的對象方法看着和其餘語言的不一樣,由於golang把那個隱藏的指針參數給展示出來了,即方法名前面的參數, 這樣好像用面向過程的思想去理解更好理解一些,即把方法名前面的參數也看作事方法的一個參數,事實上也正是這樣!eg:

func (t *Test) f1() {} ==== func f1(t *Test) {} 只是前面的是面向對象的寫法,然後面是面向過程的寫法,調用方式不一樣:

t := new(Test) t.f1()   ==== t := new(Test) f1(t)

而不加*則認爲是傳值了。


這裏還要提醒一句,對於[goroutin(程道)],[切片],[映射]這三種類型來講,只有形參,並且不須要加[*]號.


另外,對於參數類型是[interface]的函數參數,只有實參,並且不會將[interface]結構所包含的地址複製!

相關文章
相關標籤/搜索