Golang,用例指针和接口

时间:2018-04-20 08:15:35

标签: go

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

这是我的代码:

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的指针,我无法在execute()中获取指针,否则我将丢失foo类型并且无法执行库:https://play.golang.org/p/A8ETfuMQyQB。这就是我必须在newFoo()

中返回指针的原因

感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

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

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

只需将NewFooer设为Bar的成员函数即可。调用NewFooer时调用newFoo

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

最终也会调用此代码段

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

答案 1 :(得分:2)

如果你想在包中共享一个接口及其功能,你可以导出接口及其功能:

type MyInterface interface {
    GetResult() interface{}
}

当你改变Foo的实现时

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

和电话

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

它可以编译并执行而不会出现恐慌。