我正在将一些代码从C++移植到golang。我对golang中的OOP和多态性做了一些研究,都建议使用接口和嵌入来实现多态性。我有一个示例代码,如下所示type Worker interface { Show() Inc()}type WorkerA struct { x int Worker // embed all methods in interface}type WorkerB struct { WorkerA // embed WorkerA to have all methods}func (a *WorkerA) Inc() { a.x++}func (a WorkerA) Show() { fmt.Println("A:", a.x)}func (b WorkerB) Show() { fmt.Println("B:", b.x)}func main() { list := make([]Worker, 10) for n:=0; n<len(list); n++ { if n%2==0 { list[n] = &WorkerA{} } else { list[n] = &WorkerB{WorkerA{}} } } list[0].Inc() list[1].Inc() list[1].Inc() list[2].Inc() list[2].Inc() list[2].Inc() list[0].Show() list[1].Show() list[2].Show()在接口数组的帮助下,我可以在两个 Worker 之间调用相应的方法和 'WorkerBAddx'''ShowWorkerA. Now I would like to add a third method call which add thefunc (a *WorkerA) Add(b WorkerA) { a.x += b.x}我发现调用以下内容会导致错误之前是持有接口而不是结构listlist[0].Add(list[2])我在网上查找一些想法,看看可能有助于解决问题,这是我写的reflectfunc callMethodParam(p interface{}, q interface{}) { o := reflect.ValueOf(p) m := reflect.ValueOf(q) args:=[]reflect.Value{reflect.ValueOf(m)} o.MethodByName("Add").Call(args)}callMethodParam(list[0], list[2])但这似乎也行不通。任何想法如何使它工作?谢谢。
1 回答
慕的地8271018
TA贡献1796条经验 获得超4个赞
你问题的标题听起来像是一个XY问题,但幸运的是,我们知道X,是吗?
此外,代码无法像示例中显示的那样工作,因为代码被声明为 切片并且没有方法。list[0].Add(list[2])listWorkerWorkerAdd
但让我们假装它确实如此。鉴于 的实现需要访问 一个 字段,您可以更改签名以接受提供 的接口,并实现该接口:Add(b WorkerA)WorkerAxxWorkerA
type XProvider interface {
X() int
}
func (a *WorkerA) X() int {
return a.x
}
func (a *WorkerA) Add(b XProvider) {
a.x += b.X()
}
然后在调用之前,使用类型断言来确保(其中包含的类型)的特定实例也实现:a.AddWorkerXProvider
if xp, ok := list[2].(XProvider); ok {
list[0].Add(xp)
}
这是一个更新的游乐场
- 1 回答
- 0 关注
- 76 浏览
添加回答
举报
0/150
提交
取消