goang Receiver & interface
package main import (
"fmt"
) type Pointer struct {
x string
} func (this *Pointer) PrintX() {
fmt.Printf("X:%s\n", this.x)
} func (this *Pointer) SetX(str string) {
this.x = str
} type Value struct {
x string
} func (this Value) PrintX() {
fmt.Printf("X:%s\n", this.x)
} func (this Value) SetX(str string) {
this.x = str
} func main() {
p1 := Pointer{x: "Pointer"}
p1.PrintX()
p1.SetX("Pointer1")
p1.PrintX() p2 := &Pointer{}
p2.PrintX()
p2.SetX("Pointer2")
p2.PrintX() p3 := Value{x: "Value"}
p3.PrintX()
p3.SetX("Value1")
p3.PrintX() p4 := &Value{x: "value"}
p4.PrintX()
p4.SetX("Value2")
p4.PrintX()
}
运行结果:
X:Pointer
X:Pointer1
X:
X:Pointer2
X:Value
X:Value
X:value
X:value
说明:1 无论是T*作为receiver还是T类型作为接受者,都可以用实例、或者实例的指针调用函数,但是T*作为接受者将改变receiver的内容,而T类型改变的是副本,原始对象不会改变。
type Type struct {
}
type PType struct {
}
type Inter interface {
post()
}
// 接收者非指针
func (t Type) post() {
}
// 接收者是指针
func (t *PType) post() {
}
func test() {
var it Inter
//var it *Inter //接口不能定义为指针
pty := &Type{}
it = ty // 将变量赋值给接口,OK
it.post() // 接口调用方法,OK, receiver 是T
ty := Type{}
it = pty // 把指针变量赋值给接口,OK
it.post() // 接口调用方法,OK, receiver 是T
pty2 := &PType{}
it = pty2 // 把指针变量赋值给接口,OK
it.post() // 接口调用方法,OK, receiver 是*T
//ty2 := PType{}
//it = ty2 // 将变量赋值给接口,error
//it.post() // 接口调用方法,error, receiver 必须是T,而不能是T
}
详细代码:http://play.golang.org/p/KG8-Qb7gqM
为什么编译器不考虑我们的值是实现该接口的类型?接口的调用规则是建立在这些方法的接受者和接口如何被调用的基础上。下面的是语言规范里定义的规则,这些规则用来说明是否我们一个类型的值或者指针实现了该接口:
- 类型
*T的可调用方法集包含接受者为*T或T的所有方法集
这条规则说的是如果我们用来调用特定接口方法的接口变量是一个指针类型,那么方法的接受者可以是值类型也可以是指针类型。显然我们的例子不符合该规则,因为我们传入 SendNotification 函数的接口变量是一个值类型。
- 类型
T的可调用方法集包含接受者为T的所有方法
这条规则说的是如果我们用来调用特定接口方法的接口变量是一个值类型,那么方法的接受者必须也是值类型该方法才可以被调用。显然我们的例子也不符合这条规则,因为我们 Notify 方法的接受者是一个指针类型。
语言规范里只有这两条规则,我通过这两条规则得出了符合我们例子的规则:
- 类型
T的可调用方法集不包含接受者为*T的方法


Interface也是引用类型。




goang Receiver & interface的更多相关文章
- QUICK START GUIDE
QUICK START GUIDE This page is a guide aimed at helping anyone set up a cheap radio scanner based on ...
- golang实现rabbitmq消息队列失败尝试
在工作中发现,有些时候消息因为某些原因在消费一次后,如果消息失败,这时候不ack,消息就回一直重回队列首部,造成消息拥堵. 如是有了如下思路: 消息进入队列前,header默认有参数 retry_nu ...
- go test 测试用例那些事(二) mock
关于go的单元测试,之前有写过一篇帖子go test测试用例那些事,但是没有说go官方的库mock,很有必要单独说一下这个库,和他的实现原理. mock主要的功能是对接口的模拟,需要在写代码的时候定义 ...
- GoLang设计模式08 - 命令模式
命令模式是一种行为型模式.它建议将请求封装为一个独立的对象.在这个对象里包含请求相关的全部信息,因此可以将其独立执行. 在命令模式中有如下基础组件: Receiver:唯一包含业务逻辑的类,命令对象会 ...
- golang监听rabbitmq消息队列任务断线自动重连接
需求背景: goalng常驻内存任务脚本监听rbmq执行任务 任务脚本由supervisor来管理 当rabbitmq长时间断开连接会出现如下图 进程处于fatal状态 假如因为不可抗拒因素,rabb ...
- Receiver class com.mchange.v2.c3p0.impl.NewProxyResultSet does not define or inherit an implementation of the resolved method 'abstract boolean isClosed()' of interface java.sql.ResultSet.
背景: Mayabtis+springboot项目,连接数据库发生异常 报错内容: java.lang.AbstractMethodError: Receiver class com.mchange. ...
- Tun/Tap interface tutorial
Foreword: please note that the code available here is only for demonstration purposes. If you want t ...
- Interface Serializable
public interface Serializable Serializability of a class is enabled by the class implementing the ja ...
- 关于Go 的 Interface
最近在用Go语言写程序, 其中遇到一个场景:写了一个接口,3个实现接口的struct. 另外一个struct包含此接口,根据构造函数赋予不同的结构实现. 一开始struct里写的是接口的地址,但是在创 ...
随机推荐
- cs229_part7
PCA 问题背景 回顾一下我们特征选择中的问题.如果特征非常多,而且有一些特征是重复的,那么我们可以想办法剔除掉一些无用的特征.那里我们提到一个计算互信息的方法.那么这里换一种降维方法. 比如说这样的 ...
- loj2145 「SHOI2017」分手是祝愿
记 \(f_i\) 是从要做 \(i\) 步好操作变成要做 \(i-1\) 步好操作的期望操作次数. 显然 \(f_i=i/n \times 1 + (1-i/n) \times (1 + f_{i+ ...
- 【LeetCode】Add Two Numbers(两数相加)
这道题是LeetCode里的第2道题. 题目要求: 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将 ...
- 【SVN】http和https的区别
导读:输入网址的时候,经常输入http://什么什么的,但http是什么,一直都不知道.然后,这回在SVN的学习中,又出现了http和https,而且还有说https的8443端口相对优越,我就在想, ...
- iOS阴影
但是如果把masksToBounds设置为yes就没有阴影了 UIButton *view = [[UIButton alloc]initWithFrame:CGRectMake(, , , ...
- 使用Unity做2.5D游戏教程(一)
最近在研究Unity 3D,看了老外Marin Todorov写的教程很详细,就翻译过来以便自己参考,翻译不好的地方请多包涵. 如果你不了解2.5D游戏是什么,它基本上是个3D游戏而你可以想象是压扁的 ...
- BZOJ 3831: [Poi2014]Little Bird【动态规划】
Description In the Byteotian Line Forest there are trees in a row. On top of the first one, there ...
- django 和 mongdb 写一个简陋的网址,以及用django内置的分页功能
https://github.com/factsbenchmarks/simple_websit_about_58 一 设置 数据库的设置 在settings文件中加入这样一段代码: from mon ...
- day1之校花网小试牛刀
一 利用生成器来完成爬去校花网视频 import requests import re import os import hashlib import time DOWLOAD_PATH=r'D:\D ...
- STL学习笔记(五) 算法
条款30:确保目标区间足够大 条款31:了解各种与排序有关的选择 //使用unaryPred划分输入序列,使得unaryPred为真的元素放在序列开头 partition(beg, end, unar ...