go interface 的坑
一、概述
[root@node175 demo]# tree
.
├── lib
│ └── world.go
├── README
└── server.go directory, files #server.go code
package main import "fmt"
import "demo/lib" type MyPrint struct {
name string
} type Interface interface {
Print(string) error
} func (this *MyPrint) Print(who string) error {
fmt.Printf("%s name is %s\n", who, this.name)
return nil
} func NewMyPrint(name string) Interface {
return MyPrint{name: name}
} func main() {
fmt.Println("Hi, " + lib.World())
MyInterface := NewMyPrint("bob")
fmt.Printf("MyInterface type: %T\n", MyInterface)
MyInterface.Print("my")
}
运行:
[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的形式来调用方法,并不是表明值类型的对象拥有该方法。
换一个维度来看上面的表格可能更加直观:
Methods Receivers Values
-----------------------------------------------
(t T) T and *T (t *T) *T
这就意味着指针类型的receiver 方法实现接口时,只有指针类型的对象实现了该接口。
对应上面的例子来说,只有&MyPrint实现了Interface接口,而MyPrint根本没有实现该接口。所以上面代码会报出这样的异常。
MyPrint method has pointer receiver
解决这个问题也很容易,直接使用&MyPrint去代替MyPrint调用方法即可:
package main import "fmt"
import "demo/lib" type MyPrint struct {
name string
} type Interface interface {
Print(string) error
} func (this *MyPrint) Print(who string) error {
fmt.Printf("%s name is %s\n", who, this.name)
return nil
} func MyselfPrint(name string) Interface {
return &MyPrint{name: name}
} func main() {
fmt.Println("Hi, " + lib.World())
MyInterface := MyselfPrint("bob")
fmt.Printf("MyInterface type: %T\n", MyInterface)
MyInterface.Print("my")
}
或者:
package main import "fmt"
import "demo/lib" type MyPrint struct {
name string
} type Interface interface {
Print(string) error
} func (this MyPrint) Print(who string) error {
fmt.Printf("%s name is %s\n", who, this.name)
return nil
} func MyselfPrint(name string) Interface {
return MyPrint{name: name}
} func main() {
fmt.Println("Hi, " + lib.World())
MyInterface := MyselfPrint("bob")
fmt.Printf("MyInterface type: %T\n", MyInterface)
MyInterface.Print("my")
}
再或者:
package main import "fmt"
import "demo/lib" type MyPrint struct {
name string
} type Interface interface {
Print(string) error
} func (this MyPrint) Print(who string) error {
fmt.Printf("%s name is %s\n", who, this.name)
return nil
} func MyselfPrint(name string) Interface {
return &MyPrint{name: name}
} func main() {
fmt.Println("Hi, " + lib.World())
MyInterface := MyselfPrint("bob")
fmt.Printf("MyInterface type: %T\n", MyInterface)
MyInterface.Print("my")
}
go interface 的坑的更多相关文章
- Go语言第一深坑:interface 与 nil 的比较
interface简介 Go 语言以简单易上手而著称,它的语法非常简单,熟悉 C++,Java 的开发者只需要很短的时间就可以掌握 Go 语言的基本用法. interface 是 Go 语言里所提供的 ...
- 【转】GO语言map类型interface{}转换踩坑小记
原文:https://www.az1314.cn/art/69 ------------------------------------------ mapA := make([string]inte ...
- 如何一步一步用DDD设计一个电商网站(九)—— 小心陷入值对象持久化的坑
阅读目录 前言 场景1的思考 场景2的思考 避坑方式 实践 结语 一.前言 在上一篇中(如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成),有一行注释的代码: public interfa ...
- 如何设计一门语言(七)——闭包、lambda和interface
人们都很喜欢讨论闭包这个概念.其实这个概念对于写代码来讲一点用都没有,写代码只需要掌握好lambda表达式和class+interface的语义就行了.基本上只有在写编译器和虚拟机的时候才需要管什么是 ...
- .NetCore之EF跳过的坑
我在网上看到很多.netCore的信息,就动手自己写一个例子测试哈,但是想不到其中这么多坑: 1.首先.netCore和EF的安装就不用多说了,网上有很多的讲解可以跟着一步一步的下载和安装,但是需要注 ...
- AFNetWorking设置HTTPRequestHeaders的坑
今天在项目中要封装一个请求头但是用如下方法总是失败: 求其原因不知道: 于是乎改用了属性对象后居然成功了..: // // RequestManager.m // 获取天气demo // // ...
- SQL SERVER 2012/2014 链接到 SQL SERVER 2000的各种坑
本文总结一下SQL SERVER 2012/2014链接到SQL SERVER 2000的各种坑,都是在实际应用中遇到的疑难杂症.可能会有人说怎么还在用SQL SERVER 2000,为什么不升级呢? ...
- Typescript中的class interface 只是在声明,其实什么也没有干!
由于vue.js的特殊机制,初始化后给对象添加的属性是无法更新UI的. 最近结合typescript和vue进行web开发,就遇到了这样的坑. class user{ name:string; age ...
- iOS工作小技巧及填坑记录
以下是本人在iOS开发工作中使用的一些小技巧,记录一下. 1.使用XXX.pch文件便捷开发+加速Build 在IOS开发的项目中有一个XX_Prefix.pch XX_Prefix.pch:扩展名. ...
随机推荐
- JPA(二):HellWord工程
使用JPA持久化对象的操作步骤: 1)创建persistence.xml,在这个文件中配置持久化单元: --- 需要指定跟哪个数据库进行交互: --- 需要指定JPA使用哪个持久化的框架以及配置该框架 ...
- Linux Kernel 2:用户空间的初始化
上篇我们知道,kernel初始化后将启动init进程,那么这个进程将干些什么呢?除此之外,kernel还需要做些什么事情呢?(想想文件系统.根存储设备是在什么时候初始化的呢?) 先从文件系统初始化说起 ...
- GPUImage API 文档之GPUImageFilter类
GPUImageFilter类 方法 - (id)initWithVertexShaderFromString:(NSString *)vertexShaderString fragmentShade ...
- 解决CentOS下无法发送邮件的问题
最近有个项目从虚拟主机迁到云主机上,换了个环境,原来用于找回密码的发送邮件功能竟然用不了了!反应极慢,导致tenginx报504网关超时错误. 5.5 or 7.0, sockets 初次百度,看了别 ...
- KafkaOffsetMonitor 安装
KafkaOffsetMonitor 安装 1,下载KafkaOffsetMonitor-assembly-0.2.0.jar 2,启动 步骤1:启动ZK(DN1-DN3节点) zkServer. ...
- CentOS6.5安装nginx1.5.8时出现“cp: "conf/koi-win" 与"/usr/local/nginx/conf/koi-win" 为同一文件”的解决方法
安装方法主要参考了:http://www.cnblogs.com/zhoulf/archive/2013/02/09/2909653.html这篇文章,出现“cp: "conf/koi-wi ...
- 造轮子 | 怎样设计一个面向协议的 iOS 网络请求库
近期开源了一个面向协议设计的网络请求库 MBNetwork,基于 Alamofire 和 ObjectMapper 实现,目的是简化业务层的网络请求操作. 须要干些啥 对于大部分 App 而言,业务层 ...
- 微信小程序 - 支持html空格(提示)
仅限于text标签,decode参数:官方api.
- Nginx+Lua+Redis构建高并发应用
一. 源文来自:http://www.ttlsa.com/nginx/nginx-lua-redis/ 二. 预览如下:
- 机器学习-分类器-Adaboost原理
Adaboost原理 Adaboost(AdaptiveBoosting)是一种迭代算法,通过对训练集不断训练弱分类器,然后把这些弱分类器集合起来,构成强分类器.adaboost算法训练的过程中,初始 ...