use*_*400 4 types function type-conversion go
我最近了解到,在net/http包装中,有一种使用模式让我最困惑.它是功能类型转换.它是这样的:
(function a) ->convert to-> (type t)
(type t) ->implentments-> (interface i)
Run Code Online (Sandbox Code Playgroud)
因此,如果有一个以接口i作为参数的函数,它将调用函数a,这是net/http实现它的方式.
但是当我编写自己的代码时,我对这种模式有很多误解.我的代码是这样的:
package main
import (
"fmt"
)
type eat interface {
eat()
}
type aaa func()
func (op *aaa) eat() {//pointer receiver not right
fmt.Println("dog eat feels good")
}
///////////////////////////////////////////////
func dog() {
fmt.Println("I'm a dog")
}
///////////////////////////////////////////////
func feelsGood(a eat) {
a.eat()
}
func main() {
b := aaa(dog)
feelsGood(b)
}
//error:aaa does not implement eat (eat method has pointer receiver)
Run Code Online (Sandbox Code Playgroud)
类型aaa有方法eat,相同的函数名和参数签名,符合接口规则,但为什么会出错呢?接收器是否重要?
另一个问题是只有一个函数和类型,不包括接口,代码如下:
package main
import (
"fmt"
)
type aaa func()
func (op *aaa) eat() {
op()
}
///////////////////////////////////////////////
func dog() {
fmt.Println("I'm a dog")
}
///////////////////////////////////////////////
func main() {
obj:=aaa(dog)
obj.eat()
}
//error:cannot call non-function op (type *aaa)
Run Code Online (Sandbox Code Playgroud)
首先,是op一个匿名函数,不管错误是什么?
其次,我删除星号后效果很好,但为什么呢?op是类型的实例aaa,接收器是op,op代表功能狗()?http包使用f(w,r)相同的方式,但有点难以理解.是op类型,实例还是匿名函数?
看起来我对功能转换的理解是不对的,但是我也检查过Google上的很多帖子,没有一个能教我如何思考并正确使用它.谢谢你!
问题1:
在Go中,对于类型T(在您的情况下类似于aaa),T并且*T具有不同的方法集.
因此,类型T的值只能访问方法:
func(t T)Foo() { ... }
Run Code Online (Sandbox Code Playgroud)
虽然类型*T的值可以访问这两种方法:
func(t T)Foo() { ... }
func(t *T)Bar() { ... }
Run Code Online (Sandbox Code Playgroud)
在您的情况下,您有两种选择.要么声明eat方法aaa而不是od *aaa:
func (op aaa) eat() {
op()
}
Run Code Online (Sandbox Code Playgroud)
或者您将指针传递b给feelsGood:
feelsGood(&b)
Run Code Online (Sandbox Code Playgroud)
问题2:
是的,这个问题与第一个问题有关.但在这种情况下,您可以访问该方法,因为obj.eat()它将是简短的(&obj).eat().
这里的问题是你不能在函数指针(op*aaa)上调用函数.您可以选择创建方法aaa而不是*aaa:
func (op aaa) eat() {
op()
}
Run Code Online (Sandbox Code Playgroud)
或者op在值上调用函数而不是指针:
func (op *aaa) eat() {
(*op)()
}
Run Code Online (Sandbox Code Playgroud)