博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
go interface 的坑
阅读量:6633 次
发布时间:2019-06-25

本文共 3480 字,大约阅读时间需要 11 分钟。

一、概述

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 code11 package main12 13 import "fmt"14 import "demo/lib"15 16 type MyPrint struct {         17     name string               18 }19 20 type Interface interface {21     Print(string) error22 }23 24 func (this *MyPrint) Print(who string) error {25     fmt.Printf("%s name is %s\n", who, this.name)26     return nil27 }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虽然可以通过值类型和引用类型两种方式定义方法,但是不同的对象类型对应了不同的方法集:

Values                    Methods Receivers----------------------------------------------- T                        (t T)*T                        (t T) and (t *T)

  值类型的对象只有(t T) 结构的方法,虽然值类型的对象也可以调用(t *T) 方法,但这实际上是Golang编译器自动转化成了&t的形式来调用方法,并不是表明值类型的对象拥有该方法。

  换一个维度来看上面的表格可能更加直观:

1 Methods Receivers         Values2 -----------------------------------------------3 (t T)                     T and *T4 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) error12 }13 14 func (this *MyPrint) Print(who string) error {15     fmt.Printf("%s name is %s\n", who, this.name)16     return nil17 }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) error12 }13 14 func (this MyPrint) Print(who string) error {15     fmt.Printf("%s name is %s\n", who, this.name)16     return nil17 }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) error12 }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 }

 

转载于:https://www.cnblogs.com/chris-cp/p/7596089.html

你可能感兴趣的文章