golang杂记01-golang接口的赋值问题

golang中接口的赋值问题

M1: 方法–>值接受者 --> 值对象 --> 接口定义success

M2: 方法–>值接受者 --> 指针对象 --> 接口定义success

M3: 方法–>指针接受者 --> 值对象 --> 不能赋值

M4: 方法–>指针接受者 --> 指针对象 --> 接口定义success

接口


在Go语言中接口(interface)是一种类型,一种抽象的类型。

interface是一组method的集合,是duck-type programming的一种体现。接口做的事情就像是定义一个协议(规则),只要一台机器有洗衣服和甩干的功能,我就称它为洗衣机。不关心属性(数据),只关心行为(方法)。为了保护你的Go语言职业生涯,请牢记接口(interface)是一种类型。

接口的定义


type 接口类型名 interface{
        方法名1( 参数列表1 ) 返回值列表1
        方法名2( 参数列表2 ) 返回值列表2
        …
    } 
  1. 接口名:使用type将接口定义为自定义的类型名。Go语言的接口在命名时,一般会在单词后面添加er,如有写操作的接口叫Writer,有字符串功能的接口叫Stringer等。接口名最好要能突出该接口的类型含义。
  2. 方法名:当方法名首字母是大写且这个接口类型名首字母也是大写时,这个方法可以被接口所在的包(package)之外的代码访问。
  3. 参数列表、返回值列表:参数列表和返回值列表中的参数变量名可以省略。
type Sender interface {
	send(string, string) error
}

M1 案例


方法–>值接受者 --> 指针对象 --> 接口定义success

type Sender interface {
	send(string, string) error
}

type EmailSender struct {
	address  string
	port     int
	user     string
	password string
}

func (s EmailSender) send(to string, msg string) error {
	fmt.Printf("send Email to %s, The msg is : %s \n", to, msg)
	return nil
}

func main() {
	var sender Sender
	emailSender := EmailSender{"stmp.qq.com", 456, "ralph", "password"}
	sender = emailSender
	fmt.Printf("%T, %#v \n", sender, sender)
	sender.send("ralphB", "testM1")
}

OUTPUT

[root@dev1 interface]# go run intf.go 
main.EmailSender, main.EmailSender{address:"stmp.qq.com", port:456, user:"ralph", password:"password"} 
send Email to ralphB, The msg is : testM1 

M2 案例


方法–>值接受者 --> 指针对象 --> 接口定义success

type Sender interface {
	send(string, string) error
}

type EmailSender struct {
	address  string
	port     int
	user     string
	password string
}

func (s EmailSender) send(to string, msg string) error {
	fmt.Printf("send Email to %s, The msg is : %s \n", to, msg)
	return nil
}

func main() {
	var sender Sender
	per := &EmailSender{"stmp.qq.com", 456, "ralph", "password"}
	sender = per
	fmt.Printf("%T, %#v \n", sender, sender)
	sender.send("ralphB", "testM2")
}

OUTPUT

[root@dev1 interface]# go run intf.go 
*main.EmailSender, &main.EmailSender{address:"stmp.qq.com", port:456, user:"ralph", password:"password"} 
send Email to ralphB, The msg is : testM2

M3 案例


方法–>指针接受者 --> 值对象 --> 不能赋值

type Sender interface {
	send(string, string) error
}

type EmailSender struct {
	address  string
	port     int
	user     string
	password string
}

func (s *EmailSender) send(to string, msg string) error {
	fmt.Printf("send Email to %s, The msg is : %s \n", to, msg)
	return nil
}

func main() {
	var sender Sender
	emailSender := EmailSender{"stmp.qq.com", 456, "ralph", "password"}
	sender = emailSender
	fmt.Printf("%T, %#v \n", sender, sender)
    sender.send("ralphB", "testM3")
}

OUTPUT

[root@dev1 interface]# go run intf.go 
# command-line-arguments
./intf2.go:25:11: cannot use emailSender (variable of type EmailSender) as type Sender in assignment:
        EmailSender does not implement Sender (send method has pointer receiver)

M4 案例


方法–>指针接受者 --> 指针对象 --> 接口定义success

type Sender interface {
	send(string, string) error
}

type EmailSender struct {
	address  string
	port     int
	user     string
	password string
}

func (s *EmailSender) send(to string, msg string) error {
	fmt.Printf("send Email to %s, The msg is : %s \n", to, msg)
	return nil
}

func main() {
	var sender Sender
	per := &EmailSender{"stmp.qq.com", 456, "ralph", "password"}
	sender = per
	fmt.Printf("%T, %#v \n", sender, sender)
	sender.send("ralphB", "testM4")
}

OUTPUT

[root@dev1 interface]# go run intf.go 
*main.EmailSender, &main.EmailSender{address:"stmp.qq.com", port:456, user:"ralph", password:"password"} 
send Email to ralphB, The msg is : testM4 

总结

在golang中,定义了值接收者的方法,golang会默认创建它对应的指针接收者的方法。而定义了指针接收者的方法默认不会创建值接收者的方法,不过在结构体对象中定义了值对象是可以让指针接受者方法调用的,这个是因为golang自动帮我们做了取地址的语法糖

结构体对象 -> 值对象 -> 指针接受者方法 -> success!
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值