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也是引用类型。

最新文章

  1. 并发包的线程池第一篇--ThreadPoolExecutor执行逻辑
  2. VVDocumenter 使用
  3. JAVA IDE IntelliJ IDEA使用简介(一)—之界面元素
  4. Oracle提示大全
  5. linux -小记(1) 问题:"linux ifconfig查看网卡名称与配置文件不否" 或 启动网卡提示“ eth0 似乎不存在, 初始化操作将被延迟”。
  6. fstream 坑解决办法
  7. win7 MS SQL SERVER 2000安装
  8. 在C++中调用DLL中的函数 (2)
  9. iOS开发libWeChatSDK.a(WXApiObject.o)' does not contain bitcode.
  10. js 保留小数位数
  11. APUE读书笔记-第18章-终端I/O
  12. Swift - 如何实现字符串的HMAC_SHA1加密
  13. 新概念英语(1-65)Not a Baby
  14. IIS服务器如何抗住高并发的客户端访问
  15. git@github.com: Permission denied (publickey).////remote: Permission to xxx/test.git denied to xxx.等权限问题
  16. C语言:递归函数n!
  17. 基于上三角变换或基于DFS的行(列)展开的n阶行列式求值算法分析及性能评估
  18. 第49章:MongoDB-数据导入导出
  19. 假如你不小心干掉了系统,你该怎么办?(一次手贱的记录 ~ Ubuntu and Python3.6)
  20. Hive 任务优化 tips

热门文章

  1. 用java Graphics生成验证码
  2. Java中File类的使用介绍
  3. cf891a Pride
  4. 也来“玩”Metro UI之磁贴(一)
  5. 学习系列 - 马拉车&扩展KMP
  6. P1282 多米诺骨牌 (差值DP+背包)
  7. 【二叉搜索树】hdu 3791
  8. JS return false 与 return true
  9. Spring-IOC源码解读2.1-BeanDefinition的Resource定位
  10. POJ 2279