Go函数类型,该函数类型返回与接口一起使用的结构 [英] Go function types that return structs being used with interfaces

查看:46
本文介绍了Go函数类型,该函数类型返回与接口一起使用的结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一个包中有一个结构,上面有耗时的方法,并且通过它的工厂函数来构造也很耗时.因此,在依赖于其他结构的包中,我希望能够在创建后使用伪造的工厂函数和伪造的结构对其进行测试.由于该结构是通过工厂函数构造的,因此我想伪造工厂函数,并在测试期间将替代工厂函数传递给我的结构.

I have a struct in a package that has time consuming methods on it and is also time consuming to construct via it's factory function. Therefore, in the package that depends on this other struct I would like to be able to test it using both a fake factory function and a fake struct once it has been created. As the struct is constructed via a factory function I would like to fake the factory function and pass an alternative factory function into my struct during testing time.

昂贵的包裹的一个例子是:

An example of the expensive package would be:

package expensive

import "fmt"

type myStruct struct{}

func (m *myStruct) DoSomething() {
    fmt.Println("In Do something")
}

func (m *myStruct) DoSomethingElse() {
    fmt.Println("In do something else")
}

// CreateInstance is expensive to call
func CreateInstance() *myStruct {
    return &myStruct{}
}

使用它的主包如下所示:

My main package that uses this then looks like this:

package main

import "play/expensive"

func main() {
    thing := structToConstruct{expensive.CreateInstance}
    thing.performAction()
}

type myInterface interface {
    DoSomething()
}

type structToConstruct struct {
    factoryFunction func() myInterface
}

func (s *structToConstruct) performAction() {
    instance := s.factoryFunction()
    instance.DoSomething()
}

但是,此代码抱怨以下错误:

However, this code complains with the error:

.\ main.go:6:不能在字段值中使用昂贵的CreateInstance(类型func()* expensive.myStruct)作为func()myInterface类型

.\main.go:6: cannot use expensive.CreateInstance (type func() *expensive.myStruct) as type func() myInterface in field value

但是,* expensive.myStruct 确实实现了myInterface接口,所以我不明白为什么Go抱怨这种设置的类型安全性.

However, *expensive.myStruct does implement the myInterface interface so I do not understand why Go is complaining about the type safety of this setup.

此后,我意识到在@jmaloney指导下,我可以像这样在我的主要方法中包装函数:

I've since realised after @jmaloney guideance that I could just wrapper my function like this in my main method:

    wrapper := func() myInterface {
        return expensive.CreateInstance()
    }
    thing := structToConstruct{wrapper}

然后它可以工作,但是我仍然不太明白为什么当函数期望返回该接口的实例时,尤其是在不需要类型断言/转换的情况下,为什么不能使用实现接口的结构修复此问题,因为它只是调用基础工厂函数.

and this then works but I still don't really understand why I can't use a struct that implements an interface when a function is expecting an instance of that interface to be returned especially when no type assertion/conversion is necessary on this fix as it is simply just calling the underlying factory function.

此后,我遇到了将该提案添加到语言中的建议.该提案被拒绝:

I've since come across this proposal to add this to the language. The proposal was rejected:

https://github.com/golang/go/issues/12754

推荐答案

getInstance 需要返回 myInterface

package main

import "fmt"

func main() {
    var function func() myInterface

    function = getInstance

    newSomething := function()

    newSomething.doSomething()
}

type myInterface interface {
    doSomething()
}

type myStruct struct{}

func (m *myStruct) doSomething() {
    fmt.Println("doing something")
}

func getInstance() myInterface {
    return &myStruct{}
}

游乐场示例

但是,* expensive.myStruct确实实现了myInterface接口,所以我不明白为什么Go抱怨这种设置的类型安全性.

However, *expensive.myStruct does implement the myInterface interface so I do not understand why Go is complaining about the type safety of this setup.

在那种情况下,您不是在处理Go的接口,而是在处理结构的类型签名.

In that instance you were not dealing with Go's interfaces you were dealing with the type signature of your struct.

当您第一次使用 factoryFunction func()* myFunction 声明结构时,factoryFunction现在始终需要匹配声明的签名.

when you first declared your struct with factoryFunction func() *myFunction factoryFunction now always needs to match the declared signature.

这篇关于Go函数类型,该函数类型返回与接口一起使用的结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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