Go 接口在方法之间强制执行相同的参数类型(但可以是任何类型)

我敢肯定,标题令人困惑,但很难描述我的意思。


我想创建一个有两种方法的 Go 接口;第一个返回一个值,第二个接受一个值。我想确保方法 1 返回与方法 2 接受的类型相同的类型,而不指定类型是什么(除了它是一个结构)。例如:


type MyInterface interface {

    Method1() MyType

    Method2(MyType) error

}

whereMyType可以是任何类型(结构),只要它在方法 1 和方法 2 中都相同。


有没有办法在 Go 中做到这一点?


编辑:


根据@iLoveReflection 的回答,我尝试了以下方法:


package main


type MyInterface interface {

    GetType() interface{}


    UseType(input interface{})

}


type MyImplementation struct{}


type MyType struct {

}


func (i MyImplementation) GetType() MyType {

    return MyType{}

}

func (i MyImplementation) UseType(input MyType) {

    return

}


func test(input MyInterface) {

    return

}


func assertArgAndResult() {

    var v MyImplementation

    v.UseType(v.GetType())

}


func main() {

    test(MyImplementation{})

}

所以基本上,我指定了一个接口MyInterface(MyImplementation


assertArgAndResult()正在按预期工作,并确保MyImplementation满足要求。但是,我在函数中得到一个编译错误main():


cannot use MyImplementation literal (type MyImplementation) as type MyInterface in argument to test:

    MyImplementation does not implement MyInterface (wrong type for GetType method)

        have GetType() MyType

        want GetType() interface {}


红糖糍粑
浏览 122回答 1
1回答

犯罪嫌疑人X

将以下函数添加到包中,以确保在编译时输入和输出类型匹配:func assertArgAndResult() {    var v MyInterface    v.Method2(v.Method1())}只要不调用该函数,该函数就不会包含在可执行文件中。没有编译时检查可以确保它MyType是问题中指定的结构类型。reflect 包可用于完全检查类型类型。// checkItf returns true of the interface value pointed to by// pi has Method1 with some return type T and Method2 with// argument type T.func checkItf(pi interface{}) bool {    t := reflect.TypeOf(pi)    if t.Kind() != reflect.Ptr {        return false // or handle as error    }    t = t.Elem()    if t.Kind() != reflect.Interface {        return false // or handle as error    }    m1, ok := t.MethodByName("Method1")    // Method1 should have no outputs and one input.    if !ok || m1.Type.NumIn() != 0 || m1.Type.NumOut() != 1 {        return false    }    // Method2 should have one input and one output.    m2, ok := t.MethodByName("Method2")    if !ok || m2.Type.NumIn() != 1 || m2.Type.NumOut() != 1 {        return false    }    e := reflect.TypeOf((*error)(nil)).Elem()    s := m1.Type.Out(0)    // The type must be a struct and    // the input type of Method2 must be the same as the output of Method1 and    // Method2 must return error.    return s.Kind() == reflect.Struct &&        m2.Type.In(0) == s &&        m2.Type.Out(0) == e}像这样称呼它:func init() {   if !checkItf((*MyInterface)(nil)) {      panic("mismatched argument and return time son MyInterface")   }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go