指针接收器和价值接收器与Iris框架的实现差异 [英] Pointer receiver and Value receiver difference in implementation with Iris framework

查看:110
本文介绍了指针接收器和价值接收器与Iris框架的实现差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近我正在学习Iris框架。我在执行处理程序时遇到了一个问题。如下所示:

 程序包控制器

导入github.com/ kataras / iris

类型页面struct {
}

func(p * Pages)Serve(c * iris.Context){
}

为了使用这个控制器,我实现了下面的入口脚本:

package main

import(
github.com/kataras/iris



$ func main(){
ctrl:= controller.Pages {}
iris.Handle(GET, /,ctrl)
iris.Listen(:8080)
}



<但是,当我编译代码时,我收到以下错误消息:

pre $ 不能使用ctrl(类型controllers.Pages)作为在iris.Handle参数中输入iris.Handler:
controllers.Pages没有实现iris.Handler(Serve方法有指针接收器)

将声明更改为:

  ctrl:=& controller.Pages {} 

然后编译器通过,没有投诉。



问题是:我认为以下语句是平等的,因为GO编译器会在表格下进行转换:

类型Pages struct {
}

func(p * Pages)goWithPointer(){
fmt.Println(goWithPointer)
}

func(p Pages)goWithValue(){
fmt.Println(goWithValue)
}
$ b $ func main(){
p1:= Pages {}
p2:=& Pages {}

p1.goWithPointer()
p1.goWithValue()

p2.goWithPointer()
p2.goWithValue()
}

为什么我不能使用 ctrl:= controller.Pages {} 作为 iris的参数。 Handle(),而不是 ctrl:=& controller.Pages {} 作为 iris.Handle( )



感谢您的时间和分享。

解决方案

查看文档
$ b


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


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


如果您有一个接口 I ,并且 I中的部分或全部方法' s
方法集由具有 * T 的接收方法提供(其中
剩余部分由接收方为<$ c $的方法提供c> T
),那么 * T
满足接口 I ,但 T 不。这是因为 * T 的方法
set包含 T 的,但不是相反。


使用 ctrl:= Pages {} 会显示错误:

 不能使用ctrl(类型Pages)作为类型Handler在Handle参数中:
Pages不实现Handler(Serve方法有指针接收者)

使用 ctrl:= Pages {} 需要:

  func(p页)Serve(){
fmt.Println(pi)
}

Iris Handler 是一种界面类型。就像这个工作示例一样(见注释):

  package main 

导入fmt

类型处理程序接口{
服务()
}

类型页面struct {
i int
}

func(p * Pages)Serve(){
fmt.Println(pi)
}

func Handle(p Handler){
p.Serve()
}

func main(){
//在句柄的参数中不能使用ctrl(type Pages)作为类型Handler:
//页面没有实现Handler(Serve方法有指针接收器)
// ctrl:= Pages {}
ctrl:=& Pages {101}
Handle(ctrl)
}

输出:

  101 


I am studying Iris framework recently. I encountered a question when I was implementing the Handler. Like following:

package controller

import "github.com/kataras/iris"    

type Pages struct{
}

func (p *Pages) Serve(c *iris.Context) {
}

In order to use this controller, I implemented the following entry script:

package main

import (
     "github.com/kataras/iris"
     "web/controller"
)

func main(){
      ctrl := controller.Pages{}
      iris.Handle("GET", "/", ctrl)
      iris.Listen(":8080")
}

But when I compiled the code, I got the following error message:

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)

After I changed the declaration to:

ctrl := &controller.Pages{}

Then the compiler passed with no complaint.

The question is: I thought the following statements are equal, since the GO compiler will do the conversion under the table:

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()
}

Why can't I use ctrl := controller.Pages{} as the parameter to iris.Handle(), instead of ctrl := &controller.Pages{} as the parameter to iris.Handle()?

Thank you for your time and sharing.

解决方案

See Docs:

A type may have a method set associated with it. The method set of an interface type is its interface. The method set of any other type T consists of all methods declared with receiver type T. The method set of the corresponding pointer type *T is the set of all methods declared with receiver *T or T (that is, it also contains the method set of T). Further rules apply to structs containing anonymous fields, as described in the section on struct types. Any other type has an empty method set. In a method set, each method must have a unique non-blank method name.

And see: https://stackoverflow.com/a/33591156/6169399 :

If you have an interface I, and some or all of the methods in I's method set are provided by methods with a receiver of *T (with the remainder being provided by methods with a receiver of T), then *T satisfies the interface I, but T doesn't. That is because *T's method set includes T's, but not the other way around.

Using ctrl := Pages{} makes error:

cannot use ctrl (type Pages) as type Handler in argument to Handle:
Pages does not implement Handler (Serve method has pointer receiver)

Using ctrl := Pages{}needs:

func (p Pages) Serve() {
    fmt.Println(p.i)
}

Iris Handler is an interface type. like this working sample (see comment):

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

output:

101

这篇关于指针接收器和价值接收器与Iris框架的实现差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆