一、概述
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 }