Go   发布时间:2022-04-09  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了《Go in Action 2015.11.pdf》之Go’s type system大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

Interface

type notifier interface {
    notify()
}

type user struct {
    name  String
    email String
}

func (u *user) notify() {
    fmt.Printf("sending %v %v",u.email,u.Name)
}


func sendNotification(n notifier) {
    n.notify()
}
func main() {
    u := user{name: "name",email: "email"}
    sendNotification(&u)
}

代码中user实现了接口notify,但是编译执行时报错

cAnnot use u (type user) as type notifier in argument to sendNotification:
    user does not implement notifier (notify @H_265_19@method has pointer receiver)

为什么会这样呢?让我们看一下golang规范中的描述:

@H_135_79@methods Receivers
Values
T (t T)
*T (t T) and (t *T)

表格的意思是,如果给interface传入的是值,那么只能调用Receiver是值的Methods,如果给interface传入的是指针,那么能调用Receiver是值的Methods或指针的Methods.

表格反过来表示

@H_98_77@methods Receivers
Values
*T (t *T)
T (t T) and (t *T)

如果Receiver是指针,传递给interface的参数只能是指针,如果Receiver是指,那么传递给interface的参数可以是指针或指。

之所以有这样的限制在于并非所有的指都是可以取地址的。

type duration int

func (d *duration) pretty() String { return fmt.Sprintf("durantion:%d",*d) } func @H_639_64@main() { duration(23).pretty() }

程序会报错:

.\main.go:60: cAnnot call pointer @H_265_19@method on duration(23) .\@H_639_64@main.go:60: cAnnot take the address of duration(23)

duration(23)是无法取地址的。

Type embedding

golang允许使用已有的类型并扩展或改变已有类型的行为,通过Type embedding实现。Type embedding通过在struct 中嵌入已有类型实现。新的类型拥有被嵌入类型的所有成员和方法,而且可以在struct中扩展或改变被嵌入类型的方法

type user struct {
    name  String
    email String
}

func (u *user) notify() {
    fmt.Printf("sending %v %v\n",u.Name)
}

type admin struct {
    user
    Lever String
}

func main() {
    ad := admin{
        user: user{
            name:  "jonh",email: "sss@ss",},Lever: "super",}
    ad.user.notify()
    ad.notify()
}

结果

sending sss@ss jonh
sending sss@ss jonh

可以看到admin然没定义方法notify(),但是拥有了user的notify()方法
加上interface

type notifier interface {
    notify()
}

type user struct {
    name  String
    email String
}

func (u *user) notify() {
    fmt.Printf("sending %v %v\n",u.Name)
}

type admin struct {
    user
    Lever String
}

func sendNotification(n notifier) {
    n.notify()
}
func main() {
    ad := admin{
        user: user{
            name:  "jonh",}
    ad.user.notify()
    ad.notify()
    sendNotification(&ad)
}

结果

sending sss@ss jonh
sending sss@ss jonh
sending sss@ss jonh

如果admin要更改notify的话:
添加

func (u *admin) notify() { fmt.Printf("admin sending %v %v\n",u.Name) }

结果:

sending sss@ss jonh
admin sending sss@ss jonh
admin sending sss@ss jonh

可以看到notify已经更改,不过可以通过ad.user.notify()访问内部类型的方法

@H_419_320@type embedding for pointer

我们还可以将类型的指针作为嵌入类型。

type padmin struct { *user }

func main() {
    ad := padmin{
        user: &user{
            name:  "wdy",email: "000",}
    ad.user.notify()
    ad.notify()
    sendNotification(&ad)
    sendNotification(ad)
}

运行后结果:

sending 000 wdy
sending 000 wdy
sending 000 wdy
sending 000 wdy

此时我们注意到,可以给函数sendNotification直接传入ad或&ad。

sendNotification(&ad)
    sendNotification(ad)

大佬总结

以上是大佬教程为你收集整理的《Go in Action 2015.11.pdf》之Go’s type system全部内容,希望文章能够帮你解决《Go in Action 2015.11.pdf》之Go’s type system所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。