gpt4 book ai didi

go - golang 插件可以用于工厂功能吗?

转载 作者:IT王子 更新时间:2023-10-29 00:44:36 25 4
gpt4 key购买 nike

我在 golang 插件模块中有以下代码:

即插即用

package main

import "fmt"

var (
Thing = New("first thing")
ThingFactory = thingFactory{}
)

type thing struct {
i int
s string
}

func New(s string) thing {
return thing{s: s}
}

func (t *thing) Say() string {
t.i++
return fmt.Sprintf("%s - %d", t.s, t.i)
}

type thingFactory struct{}

func (t thingFactory) Make(s string) thing {
return New(s)
}

它被编译为.so 对象并在另一个程序中使用:

主.go

package main

import (
"fmt"
"plugin"
)

func main() {
p, err := plugin.Open("../plug/plug.so")
if err != nil {
panic(err)
}
symbol, err := p.Lookup("Thing")
if err != nil {
panic(err)
}
thing := symbol.(Sayer)
fmt.Println(thing.Say())

symbol, err = p.Lookup("ThingFactory") // <-problems start here
if err != nil {
panic(err)
}
factory := symbol.(GetSayer)

madeThing := factory.Make("how about me?")
fmt.Println(madeThing.Say())
fmt.Println(madeThing.Say())
}

type Sayer interface {
Say() string
}

type GetSayer interface {
Make(string) Sayer
}

我可以查找 Thing,并对其调用 Say(),但是第二个接口(interface)转换出现错误:

第一件事 - 1
panic :接口(interface)转换:*main.thingFactory 不是 main.GetSayer:缺少方法 Make

即使运行时将第一个符号识别为 Sayer,它也没有识别出 thingFactory 显然有一个 Make() 方法,它应该返回一些也是一个 Sayer。

我是否遗漏了一些明显的东西?

最佳答案

第一个问题是,在您的插件 thingFactory 中(更准确地说是 *thingfactory)没有在您的主应用程序的 GetSayer 中描述的方法界面:

Make(string) Sayer

你有:

Make(string) thing

所以(首先)您必须将 thingFactory.Make() 更改为:

type Sayer interface {
Say() string
}

func (t thingFactory) Make(s string) Sayer {
th := New(s)
return &th
}

在此之后它仍然无法正常工作。这是因为插件的 Sayer 类型与主应用程序的 Sayer 类型不同。但它们必须相同才能实现您的主应用程序的 GetSayer 接口(interface)。

一种解决方案是将 Sayer 接口(interface)“外包”到它自己的包中,并在插件和主应用程序中使用这个通用的共享包。

让我们创建一个新包,将其命名为subplay:

package subplay

type Sayer interface {
Say() string
}

导入这个包并在插件中使用它:

package main

import (
"fmt"
"path/to/subplay"
)

var (
Thing = New("first thing")
ThingFactory = thingFactory{}
)

type thing struct {
i int
s string
}

func New(s string) thing {
return thing{s: s}
}

func (t *thing) Say() string {
t.i++
return fmt.Sprintf("%s - %d", t.s, t.i)
}

type thingFactory struct{}

func (t thingFactory) Make(s string) subplay.Sayer {
th := New(s)
return &th
}

并且还在主应用程序中导入和使用它:

package main

import (
"fmt"
"path/to/subplay"
"plugin"
)

func main() {
p, err := plugin.Open("../plug/plug.so")
if err != nil {
panic(err)
}
symbol, err := p.Lookup("Thing")
if err != nil {
panic(err)
}
thing := symbol.(subplay.Sayer)
fmt.Println(thing.Say())

symbol, err = p.Lookup("ThingFactory")
if err != nil {
panic(err)
}
factory := symbol.(GetSayer)

madeThing := factory.Make("how about me?")
fmt.Println(madeThing.Say())
fmt.Println(madeThing.Say())
}

type GetSayer interface {
Make(string) subplay.Sayer
}

现在它可以工作了,输出将是:

first thing - 1
how about me? - 1
how about me? - 2

查看相关问题:

go 1.8 plugin use custom interface

How do Go plugin dependencies work?

关于go - golang 插件可以用于工厂功能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53904995/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com