指针接收器和价值接收器与Iris框架的实现差异 [英] Pointer receiver and Value receiver difference in implementation with Iris framework
问题描述
程序包控制器
导入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.
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 typeT
. The method set of the corresponding pointer type*T
is the set of all methods declared with receiver*T
orT
(that is, it also contains the method set ofT
). 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 inI
's method set are provided by methods with a receiver of*T
(with the remainder being provided by methods with a receiver ofT
), then*T
satisfies the interfaceI
, butT
doesn't. That is because*T
's method set includesT
'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屋!