英文:
How to convert interface to another interface which it implements?
问题
简而言之,我想要能够将底层类型实现了特定接口的接口类型转换为该特定接口。
我正在使用plugin包来查找一个New函数,它的样子如下(我有很多其他相同的函数):
func NewDomainPrimaryKey() any { return DomainPrimaryKey{} }
(这是在运行时生成的,所以我不能直接引用它作为DomainPrimaryKey)
我的查找和调用代码如下:
plugin, err := plugin.Open("my-plugin")
if err != nil {
return err
}
symGet, err := plugin.Lookup("New" + pluginName)
if err != nil {
return err
}
newGenModel, ok := symGet.(func() any)
if !ok {
return errors.New("unexpected type from module symbol")
}
anyGenModel := newGenModel()
genModel, ok := anyGenModel.(GenModel) // **这里出现了问题
if !ok {
return errors.New("unexpected type from module symbol")
}
genModelInstance := genModel.Get()
在上面的代码中,我试图将anyGenModel
(一个接口)转换为它实现的GenModel
接口,但是这样做不起作用。
我确定它实现了这个接口,因为当我执行以下操作时,没有出现错误。
type GenModel interface {
Get() any
TableName() string
}
var _ GenModel = (*DomainPrimaryKey)(nil) // 这没有报错
我该如何做呢?我找到了这篇文章,但我不认为它是我要找的,尽管看起来有些相似。
提前感谢您对此的任何帮助 - 这对我来说已经成为一个真正的障碍。
英文:
In short - I would like to be able to cast an interface type whose underlying type implements a specific interface to that specific interface.
I am using the plugin package to lookup a New function which looks like so (I have many others the same):
func NewDomainPrimaryKey() any { return DomainPrimaryKey{} }
(This is generated at run-time so I can't just reference it as DomainPrimaryKey)
My lookup and call is like so:
plugin, err := plugin.Open("my-plugin")
if err != nil {
return err
}
symGet, err := plugin.Lookup("New" + pluginName)
if err != nil {
return err
}
newGenModel, ok := symGet.(func() any)
if !ok {
return errors.New("unexpected type from module symbol")
}
anyGenModel := newGenModel()
genModel, ok := anyGenModel.(GenModel) // **this is where the problem is
if !ok {
return errors.New("unexpected type from module symbol")
}
genModelInstance := genModel.Get()
In the above I am trying to cast 'anyGenModel' (an interface) to the 'GenModel' interface which it implements, however, this doesn't work.
I am certain it implements this interface because when I do the following, I get no errors.
type GenModel interface {
Get() any
TableName() string
}
var _ GenModel = (*DomainPrimaryKey)(nil) // this doesn't complain
How can I do this? I found this article which I don't think is what I am looking for but seems similar.
Thanks in advance for any help on this - this has become a real blocker for me.
答案1
得分: 0
如果底层类型实现了这两个接口,那么这非常简单:
package main
import "fmt"
type IFace1 interface {
DoThis()
}
type IFace2 interface {
DoThat()
}
type impl struct{}
func (i *impl) DoThis() {
fmt.Println("I implement IFace1")
}
func (i *impl) DoThat() {
fmt.Println("I implement IFace2")
}
func GetIFace1() IFace1 {
return &impl{}
}
func main() {
i1 := GetIFace1()
i1.DoThis()
i2 := i1.(IFace2)
i2.DoThat()
}
如果你的代码不起作用,那么我会首先质疑你对anyGenModel
的底层类型是否真的实现了GenModel
接口,然后从那里开始排查。
英文:
If the underlying type implements both interfaces, this is very straightforward:
package main
import "fmt"
type IFace1 interface {
DoThis()
}
type IFace2 interface {
DoThat()
}
type impl struct{}
func (i *impl) DoThis() {
fmt.Println("I implement IFace1")
}
func (i *impl) DoThat() {
fmt.Println("I implement IFace2")
}
func GetIFace1() IFace1 {
return &impl{}
}
func main() {
i1 := GetIFace1()
i1.DoThis()
i2 := i1.(IFace2)
i2.DoThat()
}
If your code is not working, then I would begin by questioning your assertion that the underlying type of anyGenModel
actually implements GenModel
and work from there.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论