一、概述

 [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 的坑的更多相关文章

  1. Go语言第一深坑:interface 与 nil 的比较

    interface简介 Go 语言以简单易上手而著称,它的语法非常简单,熟悉 C++,Java 的开发者只需要很短的时间就可以掌握 Go 语言的基本用法. interface 是 Go 语言里所提供的 ...

  2. 【转】GO语言map类型interface{}转换踩坑小记

    原文:https://www.az1314.cn/art/69 ------------------------------------------ mapA := make([string]inte ...

  3. 如何一步一步用DDD设计一个电商网站(九)—— 小心陷入值对象持久化的坑

    阅读目录 前言 场景1的思考 场景2的思考 避坑方式 实践 结语 一.前言 在上一篇中(如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成),有一行注释的代码: public interfa ...

  4. 如何设计一门语言(七)——闭包、lambda和interface

    人们都很喜欢讨论闭包这个概念.其实这个概念对于写代码来讲一点用都没有,写代码只需要掌握好lambda表达式和class+interface的语义就行了.基本上只有在写编译器和虚拟机的时候才需要管什么是 ...

  5. .NetCore之EF跳过的坑

    我在网上看到很多.netCore的信息,就动手自己写一个例子测试哈,但是想不到其中这么多坑: 1.首先.netCore和EF的安装就不用多说了,网上有很多的讲解可以跟着一步一步的下载和安装,但是需要注 ...

  6. AFNetWorking设置HTTPRequestHeaders的坑

    今天在项目中要封装一个请求头但是用如下方法总是失败: 求其原因不知道: 于是乎改用了属性对象后居然成功了..: // //  RequestManager.m //  获取天气demo // //  ...

  7. SQL SERVER 2012/2014 链接到 SQL SERVER 2000的各种坑

    本文总结一下SQL SERVER 2012/2014链接到SQL SERVER 2000的各种坑,都是在实际应用中遇到的疑难杂症.可能会有人说怎么还在用SQL SERVER 2000,为什么不升级呢? ...

  8. Typescript中的class interface 只是在声明,其实什么也没有干!

    由于vue.js的特殊机制,初始化后给对象添加的属性是无法更新UI的. 最近结合typescript和vue进行web开发,就遇到了这样的坑. class user{ name:string; age ...

  9. iOS工作小技巧及填坑记录

    以下是本人在iOS开发工作中使用的一些小技巧,记录一下. 1.使用XXX.pch文件便捷开发+加速Build 在IOS开发的项目中有一个XX_Prefix.pch XX_Prefix.pch:扩展名. ...

随机推荐

  1. ASP入门(十三)-Server对象

    Server 对象用于处理服务器上的一些特殊任务,例如,创建组件实例.获取文件路径.执行ASP脚本文件等. Server 对象是体现 ASP 强大功能的一个对象,之前介绍的对象都是针对获取.请求以及简 ...

  2. Visual Studio 开始支持编写 Android 程序并自带 Android 模拟器【转载】

    原文地址 本文内容 为什么需要一个 Android 模拟器 针对 Visual Studio Android 模拟器的调试 Visual Studio Android 模拟器的传感器模拟和其他功能 A ...

  3. spring boot 启动找不到或无法加载主类

    转载:https://www.cnblogs.com/mrray1105/p/8137247.html 刚开始是往上面箭头指出的方向去找问题的原因,但是试了各种方法后问题还是没有解决,于是乎我把焦点转 ...

  4. phpMyadmin安装极简教程[下载,解压,登录]

    1.下载一个压缩包,例如: 2. 解压到web根目录并重命名为phpmyadmin 3.在浏览器输入http://localhost/phpmyadmin就可以看到登陆界面了,登陆之后,数据库,表的增 ...

  5. 1051: 手机(MOBILE)

    #include <iostream> #include <iomanip> #include <cstdlib> #include <string> ...

  6. dubbo高级配置学习(上)

    启动时检查 Dubbo缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止Spring初始化完成,以便上线时,能及早发现问题,默认check=true. 如果你的Spring容器是懒加载的, ...

  7. 〖Linux〗简单的将Shell和一些文件打包成一个单独的“可执行文件”

    有时候给别人分享一个工具的时候,同时需要提供的文件比较多: 如果分享一个压缩包还得教会对方如何解压.执行哪个脚本,感觉需要传输的内容多了就不方便: 把几个Shell脚本和文件打包成一个“单独的可执行文 ...

  8. ubuntu普通账户获取root权限的方法以及su和su -的区别

    打开命令窗口 输入命令:sudo passwd root 然后按照上图中的操作进行即可. su和su -的命令的不同: su命令和su -命令最大的本质区别就是:前者只是切换了root身份,但Shel ...

  9. MYSQL数据库注释

    //修改注释 alter table user comment = '我要修改注释'; //新建表设定表注释及解释说明. create table AuthUser( ID ) primary key ...

  10. 如何区分一个android app是h5的还是native

    关闭网络连接 请求一个新的界面,如果是原生的 请求失败最起码有一些基本的ui,如果h5就最多有个标题. 在wifi 设置代理,这样h5就不能正常的访问网址了会出现404 ,原生的有基本ui