为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
红糖糍粑 2022-05-05 17:40:44
我敢肯定,标题令人困惑,但很难描述我的意思。我想创建一个有两种方法的 Go 接口;第一个返回一个值,第二个接受一个值。我想确保方法 1 返回与方法 2 接受的类型相同的类型,而不指定类型是什么(除了它是一个结构)。例如:type MyInterface interface {    Method1() MyType    Method2(MyType) error}whereMyType可以是任何类型(结构),只要它在方法 1 和方法 2 中都相同。有没有办法在 Go 中做到这一点?编辑:根据@iLoveReflection 的回答,我尝试了以下方法:package maintype 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(MyImplementationassertArgAndResult()正在按预期工作,并确保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 {}
查看完整描述

1 回答

?
犯罪嫌疑人X

TA贡献2080条经验 获得超4个赞

将以下函数添加到包中,以确保在编译时输入和输出类型匹配:


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")

   }

}


查看完整回答
反对 回复 2022-05-05
  • 1 回答
  • 0 关注
  • 121 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信