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副本不会影响原来的值 内存中是两份,指针传递修改的是原有值,内存中是同一份
下面还有两篇参考文档,看完之后你应该对值接受者和指针接受者会有更好深入的理解
https://www.liangzl.com/get-article-detail-231445.html
https://blog.csdn.net/qq_31930499/article/details/93335096