一、概述

  1. [root@node175 demo]# tree
  2. .
  3. ├── lib
  4.    └── world.go
  5. ├── README
  6. └── server.go
  7.  
  8. directory, 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 NewMyPrint(name string) Interface {
  30. return MyPrint{name: name}
  31. }
  32.  
  33. func main() {
  34. fmt.Println("Hi, " + lib.World())
  35. MyInterface := NewMyPrint("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虽然可以通过值类型和引用类型两种方式定义方法,但是不同的对象类型对应了不同的方法集:

  1. Values Methods Receivers
  2. -----------------------------------------------
  3. T (t T)
  4. *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
  1.   解决这个问题也很容易,直接使用&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.  再或者:
  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 的坑的更多相关文章

  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. Angular 2的12个经典面试问题汇总(文末附带Angular測试)

    Angular作为眼下最为流行的前端框架,受到了前端开发者的普遍欢迎.不论是初学Angular的新手.还是有一定Angular开发经验的开发者,了解本文中的12个经典面试问题,都将会是一个深入了解和学 ...

  2. DOM元素尺寸offsetWidth,scrollWidth,clientWidth等具体解释

    样例: <div id="div" style="height: 200px;width: 200px;border:solid 50px red;overflow ...

  3. 关于RF对于不在屏幕内的页面元素的处理办法

    1.碰到的问题: 最近在公司用Robot framework+Selenium2Library做项目,碰到部分页面比较长,无法完全显示在屏幕内,需要上下滚动滚动条才能看到下半部分的页面元素.于是呼,问 ...

  4. Spring-boot JMS 发送消息慢的问题解决

    1:在<ActiveMQ 基于zookeeper的主从(levelDB Master/Slave)搭建以及Spring-boot下使用>(http://www.cnblogs.com/ys ...

  5. Serializable 介绍

    今天咱们简单介绍一些serializable. 1.序列化是干什么的? 简单说就是为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),并且可以把保存的对象状态再读出来.虽然你可以用你自己的各 ...

  6. SRA秘钥生成与解密

    import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java ...

  7. C# 将一个string数组转换为int数组

    int[] channelCIdArr = Array.ConvertAll(channelIdStr.Split(','),s=>int.Parse(s));

  8. Java volatile 的测试(Java代码实战-004)

    package Threads; /** * Created by xfyou 2018/5/21 16:07. */ public class VolatileTest { private stat ...

  9. 【shell】定时删除DB2表数据

    使用db2的时候,有时候需要对表数据进行删除,防止数据太多,造成数据库空间满了 以下是一个定时删除表tmp,tm1中id为1的数据的脚本 #!/bin/sh ##------------------- ...

  10. excel文字格式设置

    这里主要注意excel默认格式的设置方法,如何修改默认字体? 雅黑和4号字体? 文件----选项---常规----新建工作簿