go语言接口和方法集问题笔记

htyu_0203_39 · · 767 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

注意: 此文章只是我的个人笔记,如有谬误,错误, 请一定指出!


package main

import "fmt"

//IA test for methodset.
type IA interface {
    Value()
    Pointer()
}

//A is a  test type.
type A int

//Value receiver.
func (a A) Value() {

    fmt.Printf("Value:%p,  %d\n", &a, a)
}

//Pointer receiver.
func (a *A) Pointer() {

    fmt.Printf("Pointer:%p,  %d\n", a, *a)
}
func main() {

    //type A method set: (a A) Value()
    var a A = 1
    fmt.Printf("Origin: %p, %d\n", &a, a)
    fmt.Println("Value receiver------------------------------")
    a.Value()
    a.Pointer() //如: (&a).Value(),  a value converted to a Pointer  by go compiler, so value a can call type *A`s  pointer receiver method`

    //type *A method set: func (a A) Value(), func (a *A) Pointer()
    fmt.Println("Pointer receiver---------------------------")
    p := &a
    p.Value()
    p.Pointer()

    fmt.Println("interface call method by type *A-----------------------")
    var ia IA
    ia = &a
    ia.Value()
    ia.Pointer()

    fmt.Println("interface call method by type A-----------------------")
    //对于接口而言, 对于赋值给他的类型,会持有其副本, 即会复制, 且其持有的值不可取地址,会有更严格的类型检查和限制, 不允许做如:A to *A的转换 ,
    //所以当以类型A调用func (a *A) Pointer()时是不允许的, 因为类型A的方法集中不包括func (a *A) Pointer(), 也可以说, 类型A的方法集(method set)是类型*A的一个子集。
    //总结: 当以非接口类型调用pointer receiver method和 value receiver method时 go编译器会帮助做自动转换,如: &a 或 *a ; 所以淡化value receiver和pointer receiver方法集的边界。
    //但是接口不允许做这些自动转换, 一就是一, 严格划清方法集分界,这是golang接口的设计哲学,不是技术问题,
    //a interface must check type A or type *A , do not allow convert it between of them, so type A can not call type *A`s Pointer receiver method`
    ///ia = a //compliation error,coz type not match:  A does not implement IA (Pointer method has pointer receiver)
    //如果改成: ia = &a 就可以了, 因为:类型*A的方法集包括这个方法, 所以与接口匹配.
    //ia.Value()
    //ia.Pointer()

}

//program output:
//Origin: 0xc04200e290, 1 //注意: 与此地址不同的情况 , 皆产生了复制, 这就是value receiver与pointer receiver的区别,关注点.
//Value receiver------------------------------
//Value:0xc04200e2a8,  1
//Pointer:0xc04200e290,  1
//Pointer receiver---------------------------
//Value:0xc04200e2f0,  1
//Pointer:0xc04200e290,  1
//interface call method by type *A-----------------------
//Value:0xc04200e308,  1
//Pointer:0xc04200e290,  1

//interface call method by type A-----------------------




注意: 此文章只是我个人笔记, 如有错漏,请一定指正, 共同学习, 我的邮箱: htyu_0203_39@sina.com




有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:htyu_0203_39

查看原文:go语言接口和方法集问题笔记

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

767 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传