zoukankan      html  css  js  c++  java
  • Golang的方法传递值应该注意的地方

    其实最近看了不少Golang接口以及方法的阐述都有一个地方没说得特别明白。就是在Golang编译隐式转换传递给方法使用的时候,和调用函数时的区别。

    我们都知道,在我们为一个类型变量申明了一个方法的时候,我们可以使用类似于self.method来调用这个方法,而且无论你申明的方法的接收器是指针接收器还是值接收器,Golang都可以帮你隐式转换为正确的值供方法使用。

    让我们来看一个例子:

    package main
    
    import "fmt"
    
    type duration int
    
    func (d *duration) pretty() string {
        return fmt.Sprintf("Duration: %d", d)
    }
    
    func main() {
        var kk duration
        kk = 3
        kk.pretty()
    }

    在这个例子中,创建了一个类型为duration的变量kk,并且duration这个类型上有指针接收器的方法pretty()这个时候无论你使用kk.pretty()还有使用(&kk).pretty()都会正确执行,并且就算接收器不是指针类型而是值类型,同上一样。Golang编译器会将你传入的值隐式转换为正确的传入对象。

    这个不难理解,但是有一个跟他很像的特性,却会让这个问题变得很绕。那就是调用接口的时候出现的情况

    同样我们来看一个例子:

    package main
    
    import (
        "fmt"
    )
    
    type notifier interface {
        notify()
    }
    
    type user struct {
        name string
        email string
    }
    
    func(u *user) notify() {
        fmt.Printf("Sending user email to %s<%s>
    ",
        u.name,
        u.email)
    }
    
    func sendNotification(n notifier) {
        n.notify()
    }
    
    func main() {
        u := user{"Bill", "bill@xiachufang.com"}
        sendNotification(&u)
    }

    这个例子就不是用类型直接调用自己的方法了,而是把自己当作参数传递给接口。让接口去执行对应方法。

    这里注意,接口对于类型的要求就十分严格了,接口在神明的时候会指定,拥有哪些方法(这里的方法指 方法名, 方法参数,以及方法返回类型)。实现了这些方法就实现了这个接口。这里我们调用sendNotification这个方法需要传递进实现了notifier这个接口的变量做参数。查看notifier代码可以注意到,他实现了一个notify的方法。而我们的user实现了一个指针接收器的notify方法。但是这里注意,传递值必须遵守一个条件即:

    如果接口实现方法,类型自己的实现使用的是值接收器,那么在传递值的时候无论使用指针还是值都可以。

    如果接口实现方法,类型自己的实现使用的是指针接收器,那么在传递值的时候必须传递地址。

    所以上面的例子,接收器是指针接收器,我们必须传递地址,如果传递值则会报错。

    那么是为什么这里又不能进行隐式转换了呢?

    实际上是因为,编译器并不能总能自动获得一个值的地方,也就是说你传u,编译器不一定能知道u的地址是啥。。他可能没有办法帮你完成转换。

    Reference:

    GO IN ACTION  William Kennedy

  • 相关阅读:
    cf B. Sereja and Suffixes
    cf E. Dima and Magic Guitar
    cf D. Dima and Trap Graph
    cf C. Dima and Salad
    最短路径问题(floyd)
    Drainage Ditches(网络流(EK算法))
    图结构练习—BFSDFS—判断可达性(BFS)
    Sorting It All Out(拓扑排序)
    Power Network(最大流(EK算法))
    Labeling Balls(拓扑)
  • 原文地址:https://www.cnblogs.com/piperck/p/6550019.html
Copyright © 2011-2022 走看看