我最近正在研究虹膜框架。在实现处理程序时遇到一个问题。如下所示:
package controller import "github.com/kataras/iris" type Pages struct{ } func (p *Pages) Serve(c *iris.Context) { }
为了使用此控制器,我实现了以下输入脚本:
package main import ( "github.com/kataras/iris" "web/controller" ) func main(){ ctrl := controller.Pages{} iris.Handle("GET", "/", ctrl) iris.Listen(":8080") }
但是,当我编译代码时,收到以下错误消息:
cannot use ctrl (type controllers.Pages) as type iris.Handler in argument to iris.Handle: controllers.Pages does not implement iris.Handler (Serve method has pointer receiver)
在我将声明更改为:
ctrl := &controller.Pages{}
然后,编译器通过,没有任何抱怨。
问题是:我认为以下语句是相等的,因为GO编译器将在表下进行转换:
type Pages struct { } func (p *Pages) goWithPointer() { fmt.Println("goWithPointer") } func (p Pages) goWithValue() { fmt.Println("goWithValue") } func main() { p1 := Pages{} p2 := &Pages{} p1.goWithPointer() p1.goWithValue() p2.goWithPointer() p2.goWithValue() }
为什么我不能用ctrl := controller.Pages{}作为参数iris.Handle(),而不是ctrl := &controller.Pages{}作为参数传递给iris.Handle()?
ctrl := controller.Pages{}
iris.Handle()
感谢您的宝贵时间和分享。
参阅文件:
类型可能具有与之关联的方法集。接口类型的方法集是其接口。其他任何类型的方法集都T 包含使用接收器类型声明的所有方法T。对应的指针类型的方法集*T是使用接收器*T或声明的所有方法的集合T(也就是说,它也包含的方法集T)。进一步的规则适用于包含匿名字段的结构,如有关结构类型的部分中所述。其他任何类型的方法集都为空。在方法集中,每个方法必须具有唯一的非空白方法名称。 如果您有一个接口I,并且I方法集中的某些或全部方法是由接收者为的方法提供的*T(其余方法由接收者为的方法提供T),则*T满足该接口I,但T不满足。那是因为*T的方法集包含T,但不是这样。
类型可能具有与之关联的方法集。接口类型的方法集是其接口。其他任何类型的方法集都T 包含使用接收器类型声明的所有方法T。对应的指针类型的方法集*T是使用接收器*T或声明的所有方法的集合T(也就是说,它也包含的方法集T)。进一步的规则适用于包含匿名字段的结构,如有关结构类型的部分中所述。其他任何类型的方法集都为空。在方法集中,每个方法必须具有唯一的非空白方法名称。
T
*T
如果您有一个接口I,并且I方法集中的某些或全部方法是由接收者为的方法提供的*T(其余方法由接收者为的方法提供T),则*T满足该接口I,但T不满足。那是因为*T的方法集包含T,但不是这样。
I
使用ctrl := Pages{}制造错误:
ctrl := Pages{}
cannot use ctrl (type Pages) as type Handler in argument to Handle: Pages does not implement Handler (Serve method has pointer receiver)
使用ctrl := Pages{}需求:
func (p Pages) Serve() { fmt.Println(p.i) }
虹膜处理程序是一种接口类型。像这个工作示例(请参阅评论):
package main import "fmt" type Handler interface { Serve() } type Pages struct { i int } func (p *Pages) Serve() { fmt.Println(p.i) } func Handle(p Handler) { p.Serve() } func main() { // cannot use ctrl (type Pages) as type Handler in argument to Handle: // Pages does not implement Handler (Serve method has pointer receiver) //ctrl := Pages{} ctrl := &Pages{101} Handle(ctrl) }
输出:
101