繁体   English   中英

go reflection:获取正确的struct类型的接口

[英]go reflection: get correct struct type of interface

考虑一下:

type myStruct struct {
    Foo string `json:"foo"`
}

func main() {
    somelibrary.DoThing(func(thing myStruct) {
        // myStruct should contain unmarshaled JSON
        // provided by somelibrary

        fmt.Printf("%v\n", thing)
    })
}

我是Go的新手,所以我担心这可能不是惯用的代码。 我想实现somelibrary.DoThing以便通过反射正确地从函数参数中推断出结构类型,如果可能的话。 这就是我所拥有的:

const jsonData := []byte{`{"foo": "bar"}`}

func DoThing(fn interface{}) {
    // Get first arg of the function
    firstArg := reflect.TypeOf(fn).In(0)
    structPtr := reflect.New(firstArg)

    // Convert to Interface
    // Note that I can't assert this to .(myStruct) type
    instance := structPtr.Elem().Interface()

    // Unmarshal the JSON
    json.Unmarshal(jsonData, &instance)

    // Call the function
    vfn := reflect.ValueOf(fn)
    vfn.Call([]reflect.Value{reflect.ValueOf(instance)})
}

事先不知道结构类型,json.Unmarshal只假设instancemap[string]interface{} ,所以在调用vfn.Call(...)时我会感到恐慌:

panic: reflect: Call using map[string]interface {} as type main.myStruct

是否可以将instance接口转换为正确的类型? 换句话说,我可以通过传递字符串(或使用一些反射方法)而不是将程序可用的类型作为符号来键入类型断言吗?

是的,这是可能的。 这是您的代码更新:

func DoThing(fn interface{}) {
    // Get first arg of the function
    firstArg := reflect.TypeOf(fn).In(0)

    // Get the PtrTo to the first function parameter
    structPtr := reflect.New(firstArg)

    // Convert to Interface
    // Note that I can't assert this to .(myStruct) type
    instance := structPtr.Interface()

    // Unmarshal the JSON
    json.Unmarshal(jsonData, instance)

    // Call the function
    vfn := reflect.ValueOf(fn)
    vfn.Call([]reflect.Value{structPtr.Elem()})
}

做出的改变:

  1. structPtr (一个指针)传递给json.Unmarshal ; 传递一个值,您将看不到更改
  2. 传递给json.Unmarshal时删除获取instance的地址; 通常没有一个很好的理由有一个指向接口的指针
  3. 在调用fn时使用structPtr而不是instance

https://play.golang.org/p/POmOyQBJYC

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM