码迷,mamicode.com
首页 > 其他好文 > 详细

go interface 的坑

时间:2017-09-26 12:53:35      阅读:215      评论:0      收藏:0      [点我收藏+]

标签:编译器   表格   概念   arguments   调用   files   值类型   package   demo   

一、概述

 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 }
 

go interface 的坑

标签:编译器   表格   概念   arguments   调用   files   值类型   package   demo   

原文地址:http://www.cnblogs.com/chris-cp/p/7596089.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!