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

 

posted on 2021-01-19 18:22  EZgod  阅读(336)  评论(1编辑  收藏  举报