美文网首页
关于指针接收者和值接收者

关于指针接收者和值接收者

作者: 普朗tong | 来源:发表于2020-04-18 12:53 被阅读0次

方法

方法能给用户定义的类型添加新的行为。方法实际上也是函数,只是在声明时,在关键字func 和方法名之间增加了一个参数,可以参考如下示例:

// 这个示例程序展示如何声明
// 并使用方法
package main

import (
    "fmt"
)

// user在程序里定义一个用户类型
type user struct {
    name  string
    email string
}

// notify使用值接收者实现了一个方法
func (u user) notify() {
    fmt.Printf("Sending User Email To %s<%s>\n", u.name,
        u.email)
}

// changeEmail使用指针接收者实现了一个方法,可以修改原数据
func (u *user) changeEmail(email string) {

    u.email = email

}

// changeName使用值接收者实现了一个方法,由于user是结构体,属于值类型,因此无法修改原数据
func (u user) changeName(name string) {

    u.name=name

}

func main() {
    // user类型的值可以用来调用
    // 使用值接收者声明的方法
    bill := user{"Bill", "bill@email.com"}
    bill.notify()

    // 指向 user 类型值的指针也可以用来调用
    // 使用值接收者声明的方法
    lisa := &user{"Lisa", "lisa@email.com"}
    lisa.notify()

    // user类型的值也可以用来调用
    // 使用指针接收者声明的方法
    // 实际上:Go编译器为了支持这种方法调用将bill.changeEmail("bill@newdomain.com")转为(&bill).changeEmail ("bill@newdomain.com")
    // 由于是指针,所以可以实现修改原数据
    bill.changeEmail("bill@newdomain.com")
    bill.notify()

    // 指向 user 类型值的指针可以用来调用
    // 使用指针接收者声明的方法
    // 实际上:Go编译器为了支持这种方法调用,指针被解引用为值,lisa.notify()转为(*lisa).notify()
    lisa.changeEmail("lisa@newdomain.com")
    lisa.notify()

    //分析同上,
    bill.changeName("david")
    bill.notify()

    lisa.changeName("lucy")
    lisa.notify()

}
//输出:
Sending User Email To Bill<bill@email.com>
Sending User Email To Lisa<lisa@email.com>
Sending User Email To Bill<bill@newdomain.com>
Sending User Email To Lisa<lisa@newdomain.com>
Sending User Email To Bill<bill@newdomain.com>
Sending User Email To Lisa<lisa@newdomain.com>

关键字 func 和函数名之间的参数被称作接收者,将函数与接收者的类型绑在一起。如果一个函数有接收者,这个函数就被称为方法

使用值接收者还是指针接收者

是使用值接收者还是指针接收者,不应该由该方法是否修改了接收到的值来决定。这个决策 应该基于该类型的本质。这条规则的一个例外是,需要让类型值符合某个接口的时候,即便类型的本质是非原始本质的,也可以选择使用值接收者声明方法。这样做完全符合接口值调用方法的机制

接口

接口是用来定义行为的类型。这些被定义的行为不由接口直接实现,而是通过方法由用户 定义的类型实现。如果用户定义的类型实现了某个接口类型声明的一组方法,那么这个用户定 义的类型的值就可以赋给这个接口类型的值。这个赋值会把用户定义的类型的值存入接口类型 的值。
对接口值方法的调用会执行接口值里存储的用户定义的类型的值对应的方法。因为任何用户 定义的类型都可以实现任何接口,所以对接口值方法的调用自然就是一种多态。在这个关系里, 用户定义的类型通常叫作实体类型,原因是如果离开内部存储的用户定义的类型的值的实现,接口值并没有具体的行为


实体值赋值后接口值
实体指针赋值后接口值

方法集

如果使用指针接收者来实现一个接口,那么只有指向那个类型的指针才能够实现对应的接口。如果使用值接收者来实现一个接口,那么那个类型的值和指针都能够实现对应的接口


方法集规则

相关文章

  • Go 函数值接收者和指针接收者

    值接收者和指针接收者 值接收者使用值接收者声明方法,调用者会用这个值的一个副本来执行 指针接收者使用指针接收者声明...

  • 6-数据类型内存结构-interface

    1. 值接收者和指针接收者 实现了接收者是值类型的方法, 自动生成 了接收者是指针类型的方法; 实现了接收者是指针...

  • 23 Golang中的接口(三)

    结构体值接收者和指针接收者实现接口的区别 值接收者如果结构体中的方法是值接收者,那么实例化后的结构体值类型和指针类...

  • 关于指针接收者和值接收者

    方法 方法能给用户定义的类型添加新的行为。方法实际上也是函数,只是在声明时,在关键字func 和方法名之间增加了一...

  • golang函数接收器及安全问题 2022-10-20

    不管接收者类型是值类型还是指针类型,都可以通过值类型或指针类型调用 实际上,当类型和方法的接收者类型不同时,其实是...

  • 关于Golang的接收者和指针接收者

    接收者 接收者是将操作副本,可以理解成,在每一个方法中,它对属性的操作都是先创建一个该属性的副本,接着操作副本。 ...

  • 2018-01-10

    是使用值接收者还是指针接收者,不应该由该方法是否修改了接收到的值来决定。这个决策 应该基于该类型的本质

  • Go 中的方法集合指针接收者和值接收者

    在Go语言中,可以给用户定义的类型添加新的行为。方法其实也是函数,只是在声明时,在关键字func和方法名之间增加了...

  • Go中方法接收者是指针类型和值类型的根本区别, 看这一篇就足够了

    要理解使用指针接收者和使用值接收者的根本区别只需要明确一点就够了:它们的方法名是不一样的。 方法名 我们拿Man和...

  • go 方法

    Go 既允许使用值,也允许使用指针来调用方法,不必严格符合接收者的类型。

网友评论

      本文标题:关于指针接收者和值接收者

      本文链接:https://www.haomeiwen.com/subject/knlvvhtx.html