1. 程式人生 > 實用技巧 >go 值接受者和指標接受者的區別

go 值接受者和指標接受者的區別

func (config *Config) ParseYaml() *Config {
    yamlFile, err := ioutil.ReadFile(yamlconfig)
    if err != nil {
        log.Printf("yamlFile.Get err   #%v ", err)
    }
    err1 := yaml.Unmarshal(yamlFile, config)
    if err != nil {
        fmt.Printf("%v", err1)
    }
    return config

}

func (config Config) ParseYaml1() Config {

    conf:
=&Config{} yamlFile, err := ioutil.ReadFile(yamlconfig) if err != nil { fmt.Println(err) } err1 := yaml.Unmarshal(yamlFile, conf) if err1 != nil { fmt.Println(err1) } return *conf }

以上示例中接受者分別是*Config和Config

我們來看看我們怎麼呼叫這兩種方法的:

*Config的呼叫方式:

var config =service.Config{}
config.ParseYaml()
fmt.Println(config.Database)

Config的呼叫方式如下:

var config =service.Config{}
conf:=config.ParseYaml1()
fmt.Println(conf.Database)

專案的目錄結構如下:

仔細看看這兩種呼叫方式:

1,對於*Config來說其實是就相當於Java中的this,在呼叫時把config的引用(這裡是指標)傳遞給了 方法,此時在方法裡可以直接拿到config(java 叫引用,go叫指標)對其進行操作,在呼叫時GO 語言隱式的取了config的 指標&config,我們在unMarshal是就會吧相應的值存進這個引用(指標所指向)的值當中,所以我們沒必要再來建立變數來接收他,直接用其自身就可以,當然你不嫌麻煩也可以在定義變數去引用他,這時新的變數的型別是指標型別

2,對於Config的呼叫方式,其實這裡是將原始的值copy了一份給方法,方法拿到這個值是一份copy 你可以列印這兩個變數的指標記憶體地址指向的是不同的區域,這是想用這個copy的config(這裡也可以不適用他,像我這裡就是重新建立了一個新的值,但這是多此一舉,沒必要,也會浪費記憶體,所以不建議這樣搞,我這裡只是為了好演示好理解才這麼搞得),我們需要用他的指標&config再傳入unMarshal 然後返回時再轉成值*config,因為返回值是值型別而非指標型別

這裡基本上就講完了

有一句話是前人總結的

值傳遞修改的copy副本不會影響原來的值 記憶體中是兩份,指標傳遞修改的是原有值,記憶體中是同一份