go 值接受者和指標接受者的區別
阿新 • • 發佈:2021-01-19
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副本不會影響原來的值 記憶體中是兩份,指標傳遞修改的是原有值,記憶體中是同一份