使用Iris框架实现指针接收器和值接收器的差异

时间:2016-08-17 02:57:13

标签: go

我最近正在研究Iris框架。我在实现Handler时遇到了一个问题。如下:

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()的参数?

感谢您的时间和分享。

2 个答案:

答案 0 :(得分:2)

See Docs

  

类型可能具有与之关联的方法集。方法集   接口类型是它的接口。任何其他类型T的方法集   由接收器类型T声明的所有方法组成。方法集   对应的指针类型*T是所有方法的集合   用接收者*TT声明(也就是说,它也包含方法   T)的集合。进一步的规则适用于包含匿名字段的结构,   如结构类型一节中所述。任何其他类型都有   空方法集。在方法集中,每个方法必须具有唯一性   非空方法名称。

请参阅:https://stackoverflow.com/a/33591156/6169399

  

如果你有一个界面I,以及I中的部分或全部方法   方法集由具有*T的接收器的方法提供(带有   余数由接收方为T)的方法提供,然后*T   满足界面I,但T没有。那是因为*T的方法   set包含T,但不是相反。

使用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)
}

Iris Handler是一种接口类型。喜欢这个工作样本(见评论):

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

答案 1 :(得分:0)

根据https://godoc.org/github.com/kataras/iris#Handler。 Iris Handler是一种接口类型。

GO仅对变量执行隐式指针转换,而不是在接口上执行。