首页 文章

Golang,用例指针和接口

提问于
浏览
2

我正在编写一个我需要在我的程序的其他部分使用的库,因为我必须使用很多接口而且我最终遇到了一个我不知道如何解决的问题 .

这是我的代码:

main.go

package main

import (
    "test/bar"
)

// Foo is defined in another package
type Foo struct {
    WhatWeWant string
}

func (f *Foo) getResult() interface{} {
    return f.WhatWeWant
}

func newFoo() interface{} {
    return &Foo{
        WhatWeWant: "test",
    }
}

func main() {
    bar := bar.Bar{
        NewFooer: newFoo,
    }
    bar.Execute()
}

酒吧/ bar.go

package bar

import (
    "fmt"
    "reflect"
)

type myInterface interface {
    getResult() interface{}
}

type Bar struct {
    NewFooer func() interface{}
}

func (b *Bar) Execute() {
    foo := b.NewFooer()

    // executeLib only accept pointer
    executeLibWrapper(foo)

    whatWeWant := foo.(myInterface).getResult()
    fmt.Println(whatWeWant)
    fmt.Println("Win!")

}

// This function is executed in an external library I have no control on
func executeLibWrapper(src interface{}) {
    executeLib(reflect.TypeOf(src))
}

func executeLib(src reflect.Type) {

    if src.Kind() == reflect.Ptr {
        executeLib(src.Elem())
        return
    }

    switch src.Kind() {
    case reflect.Struct:
        fmt.Println("Struct OK!")
    default:
        panic(fmt.Sprintf("Can't detect struct, we detect %s", src.Kind()))
    }
}

我收到了错误

panic: interface conversion: *main.Foo is not bar.myInterface: missing method getResult

我的目标是能够在执行库之后调用getResult() . 这是一个游乐场:https://play.golang.org/p/7G2wc6uGngH . 这个游乐场很有效,因此很有可能这个问题来自它在不同包装中的事实 .

请注意,我需要传递一个指向executeLib的指针,我可以't get the pointer in execute() because otherwise I' ll丢失foo类型并且无法执行库:https://play.golang.org/p/A8ETfuMQyQB . 这就是我必须在newFoo()中返回指针的原因

谢谢您的帮助 !

2 回答

  • 2

    如果要跨包共享一个接口及其func,则导出接口及其func:

    type MyInterface interface {
        GetResult() interface{}
    }
    

    当你改变Foo的实现时

    func (f *Foo) GetResult() interface{} {
        return f.WhatWeWant
    }
    

    和电话

    whatWeWant := foo.(MyInterface).GetResult()
    

    它编译和执行没有恐慌 .

  • 3

    得到了结果here . 希望这可以提供帮助 .

    似乎诀窍是使用这些 . 添加这些代码段会对代码产生最小的影响 .

    只需使 NewFooer 成为 Bar 的成员函数 . 调用 NewFooer 时调用 newFoo .

    func (m *Bar) NewFooer() interface{} {
        return newFoo()
    }
    

    最终也会调用此代码段

    func newFoo() interface{} {
        return &Foo{
            WhatWeWant: "test",
        }
    }
    

相关问题