go interface 的坑
一、概述
1 [root@node175 demo]# tree 2 . 3 ├── lib 4 │ └── world.go 5 ├── README 6 └── server.go 7 8 1 directory, 3 files 9 10 #server.go code 11 package main 12 13 import "fmt" 14 import "demo/lib" 15 16 type MyPrint struct { 17 name string 18 } 19 20 type Interface interface { 21 Print(string) error 22 } 23 24 func (this *MyPrint) Print(who string) error { 25 fmt.Printf("%s name is %s\n", who, this.name) 26 return nil 27 } 28 29 func MyselfPrint(name string) Interface { 30 return MyPrint{name: name} 31 } 32 33 func main() { 34 fmt.Println("Hi, " + lib.World()) 35 MyInterface := MyselfPrint("bob") 36 fmt.Printf("MyInterface type: %T\n", MyInterface) 37 MyInterface.Print("my") 38 }
运行:
[root@node175 demo]# go run server.go
# command-line-arguments
./server.go:20: cannot use MyPrint literal (type MyPrint) as type Interface in return argument:
MyPrint does not implement Interface (Print method has pointer receiver)
为了解决这个问题,首先得先了解一下Golang 中 方法的集合的概念,一个struct虽然可以通过值类型和引用类型两种方式定义方法,但是不通的对象类型对应了不同的方法集:
Values Methods Receivers -----------------------------------------------T (t T) *T (t T) and (t *T)
值类型的对象只有(t T) 结构的方法,虽然值类型的对象也可以调用(t *T) 方法,但这实际上是Golang编译器自动转化成了&t的形式来调用方法,并不是表明值类型的对象拥有该方法。
换一个维度来看上面的表格可能更加直观:
1 Methods Receivers Values 2 ----------------------------------------------- 3 (t T) T and *T 4 5 (t *T) *T
这就意味着指针类型的receiver 方法实现接口时,只有指针类型的对象实现了该接口。
对应上面的例子来说,只有&MyPrint实现了Interface接口,而MyPrint根本没有实现该接口。所以上面代码会报出这样的异常。
1 MyPrint method has pointer receiver
解决这个问题也很容易,直接使用&MyPrint去代替MyPrint调用方法即可:
1 package main 2 3 import "fmt" 4 import "demo/lib" 5 6 type MyPrint struct { 7 name string 8 } 9 10 type Interface interface { 11 Print(string) error 12 } 13 14 func (this *MyPrint) Print(who string) error { 15 fmt.Printf("%s name is %s\n", who, this.name) 16 return nil 17 } 18 19 func MyselfPrint(name string) Interface { 20 return &MyPrint{name: name} 21 } 22 23 func main() { 24 fmt.Println("Hi, " + lib.World()) 25 MyInterface := MyselfPrint("bob") 26 fmt.Printf("MyInterface type: %T\n", MyInterface) 27 MyInterface.Print("my") 28 }
或者:
1 package main 2 3 import "fmt" 4 import "demo/lib" 5 6 type MyPrint struct { 7 name string 8 } 9 10 type Interface interface { 11 Print(string) error 12 } 13 14 func (this MyPrint) Print(who string) error { 15 fmt.Printf("%s name is %s\n", who, this.name) 16 return nil 17 } 18 19 func MyselfPrint(name string) Interface { 20 return MyPrint{name: name} 21 } 22 23 func main() { 24 fmt.Println("Hi, " + lib.World()) 25 MyInterface := MyselfPrint("bob") 26 fmt.Printf("MyInterface type: %T\n", MyInterface) 27 MyInterface.Print("my") 28 }
再或者:
1 package main 2 3 import "fmt" 4 import "demo/lib" 5 6 type MyPrint struct { 7 name string 8 } 9 10 type Interface interface { 11 Print(string) error 12 } 13 14 func (this MyPrint) Print(who string) error { 15 fmt.Printf("%s name is %s\n", who, this.name) 16 return nil 17 } 18 19 func MyselfPrint(name string) Interface { 20 return &MyPrint{name: name} 21 } 22 23 func main() { 24 fmt.Println("Hi, " + lib.World()) 25 MyInterface := MyselfPrint("bob") 26 fmt.Printf("MyInterface type: %T\n", MyInterface) 27 MyInterface.Print("my") 28 }
go interface 的坑相关推荐
- struct interface_golang 避坑指南(1)interface 之坑多多 | 文末深圳 Meetup
点击上方蓝色"Go语言中文网"关注我们,领全套Go资料,每天学习 Go 语言 interface{}和void*/Object 是一样的吗? 先来看一段关于 interface 的 ...
- Star CCM+ Interface踩坑——表面发射率
本文讨论计算辐射传热时多个计算域之间接触面上的发射率问题. 以下面这个简单模型为例子,该模型有三个计算域,上.下都是金属铝固体,中间是空气,空气域这里简化为透明固体,忽略其导热(导热系数取1e-5 W ...
- daily CodeWars
每天都在codewars做题,刷题. 记录一下.. CodeWars Javascript filter - 1 function searchNames(logins){return logins. ...
- 建站四部曲之后端接口篇(SpringBoot+上线)
本系列分为四篇: 建站四部曲之后端接口篇(SpringBoot+上线) 建站四部曲之Python数据爬虫篇(selenium) 建站四部曲之前端显示篇(React+上线) 建站四部曲之移动端篇(And ...
- Go语言第一深坑 - interface 与 nil 的比较 (转)
http://studygolang.com/articles/10635 转载于:https://www.cnblogs.com/majianguo/p/7426320.html
- 【golang程序包推荐分享】分享亿点点golang json操作及myJsonMarshal程序包开发的踩坑经历 :)
目录[阅读时间:约5分钟] 一.概述 1.Json的作用 2.Go官方 encoding/json 包 3. golang json的主要操作 二.Json Marshal:将数据编码成json字符串 ...
- (转)面试必备技能:JDK动态代理给Spring事务埋下的坑!
一.场景分析 最近做项目遇到了一个很奇怪的问题,大致的业务场景是这样的:我们首先设定两个事务,事务parent和事务child,在Controller里边同时调用这两个方法,示例代码如下: 1.场景A ...
- 天天都会写接口(interface),但它的用途和好处有多少人能说得清楚?
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:nvd11 blog.csdn.net/nvd11/arti ...
- 面试官问我,使用Dubbo有没有遇到一些坑?我笑了。
作者:肥朝 来自:feichao_java 前言 17年的时候,因为一时冲动没把持住(当然最近也有粉丝叫我再冲动一把再更新一波),结合面试题写了一个系列的Dubbo源码解析.目前公众号大部分粉丝都是之 ...
最新文章
- NodeJS入门--环境搭建 IntelliJ IDEA
- JDK1.8源码分析:线程安全的CopyOnWriteArrayList与CopyOnWriteArraySet
- 苦逼网管员----何时能翻身!
- 架构师修练 I - 超级代码控
- python计算不规则图形面积_python opencv中的不规则形状检测和测量
- springMVC实现增删改查
- 没有光芯片,何谈 5G 与 AI !
- Linux资源控制-CPU和内存【转】
- matlab指数分布拟合,如何使用matlab拟合指数分布函数?
- python进阶到高阶大全(强烈推荐)
- 眼睛容易干燥疲劳怎么办?
- 学习《医学三字经白话解》之医学源流+中风
- 排序算法,对内存小数据量大的数据排序(一)
- Antd 表格样式修改
- 经典的测试开发面试题
- 介绍解决方案、项目和项
- opencv-python读取摄像头视频流保存为视频
- 关于电信基站nid,sid,bid
- 计算机二级有重复的题目吗,计算机二级能重复考吗
- 线性代数精华——从正交向量到正交矩阵