Go 无法使用';func(c容器)接口{}{return&;MyService{}}';(类型func(c容器)接口{})作为类型ContainerFunc

Go 无法使用';func(c容器)接口{}{return&;MyService{}}';(类型func(c容器)接口{})作为类型ContainerFunc,go,goland,Go,Goland,我试图理解如何构建一个服务容器。虽然这不是一个推荐的过程,但我还是想从中学习一些东西 但在构建了如下图所示的代码之后 我收到一条如下的错误消息 源代码: 封装单元 进口( “测试” “github.com/stretchr/authentic/assert” 框架“../../framework” ) 类型ContainerFunc func(容器容器)接口{} 类型MyService struct{ 名称字符串 } 类型Container framework.Container func T

我试图理解如何构建一个服务容器。虽然这不是一个推荐的过程,但我还是想从中学习一些东西

但在构建了如下图所示的代码之后

我收到一条如下的错误消息

源代码:

封装单元
进口(
“测试”
“github.com/stretchr/authentic/assert”
框架“../../framework”
)
类型ContainerFunc func(容器容器)接口{}
类型MyService struct{
名称字符串
}
类型Container framework.Container
func TestContainerSingleton(t*testing.t){
c:=framework.New()
assert.False(t,c.Has(“test.service.name”))
assert.Equal(t,[]字符串{},c.GetKeys())
c、 Set(“my.service”,func(c容器)接口{}{
return&MyService{}
})
}
集装箱

包框架
进口(
“fmt”
“日志”
“反映”
“同步”
)
//容器用于包含任何服务
类型容器接口{
集合(名称字符串,f ContainerFunc)
Has(名称字符串)bool
获取(名称字符串)接口{}
GetKeys()[]字符串
填充(名称字符串,ds接口{})
扩展(名称字符串,f extender func)
}
//ContainerFunc将根据需要生成接口
类型ContainerFunc func(容器容器)接口{}
//Extender Func表示接口
类型扩展函数接口{}
类型容器结构{
值映射[string]容器函数
扩展映射[string][]reflect.Value
服务映射[字符串]接口{}
mtx*sync.RWMutex
}
//New方法初始化一个新容器并返回它。
func New()容器{
退货和集装箱{
服务:make(映射[string]接口{}),
值:make(映射[string]ContainerFunc),
扩展:make(映射[string][]reflect.Value),
mtx:&sync.RWMutex{},
}
}
/*
在集合中存储容器的方法
*/
func(c*容器)集(名称字符串,f ContainerFunc){
c、 mtx.Lock()
延迟c.mtx.Unlock()
//检查服务是否符合格式,服务是否存在会引发恐慌
如果,ok:=c.services[name];ok{
log.Panic(“无法覆盖已初始化的服务”)
}
c、 值[名称]=f
fmt.Printf(“%s服务已注册”,名称)
}
/*
检查映射中是否存在该名称并返回布尔值
它首先锁定c.值进行读取,然后检查,最后使用
延迟它释放锁
*/
func(c*容器)有(名称字符串)bool{
//在值映射上应用读锁
c、 mtx.RLock()
//回叫后释放锁
延迟c.mtx.RUnlock()
//检查该值是否存在,并将布尔值放入“ok”变量中
如果u,确定:=c.values[name];确定{
返回真值
}
返回错误
}
func(c*容器)Get(名称字符串)接口{}{
//锁定从c值读取的数据
c、 mtx.RLock()
_,确定:=c.values[name]
//读取后将其解锁,并将布尔值放入ok变量
c、 mtx.RUnlock()
//如果它是错误的,那就是一个错误
如果!好的{
死机(fmt.Sprintf(“服务不存在:%s”,名称))
}
//如果没有触发恐慌
//从读取锁定服务
c、 mtx.RLock()
//检查名称是否在服务中
_,ok=c.services[名称]
//阅读并解锁服务地图
c、 mtx.RUnlock()
//ok(布尔值)为false类型,将容器定义为“v”变量中的c
如果!好的{
v:=c.值[名称](c)
c、 mtx.RLock()
c、 服务[名称]=v
c、 mtx.RUnlock()
//它在地图上划过,然后。。。。
如果扩展,确定:=c.extends[name];确定{
对于u,extend:=范围扩展{
//创建一片反射值
结果:=extend.Call([]reflect.Value{reflect.ValueOf(v),reflect.ValueOf(c)})
c、 mtx.Lock()
c、 服务[名称]=结果[0]。接口()
c、 mtx.Unlock()
}
}
}
c、 mtx.RLock()
延迟c.mtx.RUnlock()
返回c.services[名称]
}
//如果发生任何情况,Fill将返回错误
func(c*容器)填充(名称字符串,dst接口{}){
//获取结构
obj:=c.Get(名称)
//使用fill函数在dst接口中添加了元素
如果错误:=填充(obj,dst);错误!=无{
log.Panic(错误)
}
}
//Extend主要控制c.extends,它附加了一个回调函数
func(c*容器)扩展(名称字符串,f extender func){
c、 mtx.Lock()
延迟c.mtx.Unlock()
如果,ok:=c.services[name];ok{
log.Panic(“无法扩展已初始化的服务”)
}
如果u,确定:=c.values[name];!确定{
log.panif(“无法扩展%s服务”,名称)
}
c、 extends[name]=append(c.extends[name],reflect.ValueOf(f))
}
//Get keys主要创建一个空映射,用字符串填充映射中的所有值
//通过追加并返回映射
func(c*容器)GetKeys()[]字符串{
c、 mtx.RLock()
延迟c.mtx.RUnlock()
键:=make([]字符串,0)
对于k:=范围c.值{
keys=追加(keys,k)
}
返回键
}
//fill方法只需向dest接口(正在注入)添加一个元素
func fill(src,dest接口{})(错误){
延迟函数(){
如果r:=recover();r!=nil{
d:=反射类型(目的地)
s:=reflect.TypeOf(src)
err=fmt.Errorf(“填充目标应该是指向%s的指针,但您使用了%s”,s,d)
}
}()
reflect.ValueOf(dest.Elem().Set(reflect.ValueOf(src))
返回错误
}
我收到的错误信息,知道如何解决吗

无法使用“func(c容器)接口{}{return&MyService{}” (类型func(c容器)接口{})作为类型ContainerFunc


如果我试图重建您的情况(使用Go 1.13)
./unit.go:25:22: cannot use func literal (type func(Container) interface {})
as type framework.ContainerFunc in argument to c.Set
type Container framework.Container
type Container = framework.Container