繁体   English   中英

如何使函数的参数成为“通用”结构

[英]How to make parameter of function is a “generic” struct

例如,我要编写这样的方法:

func parseData(rawData []json.RawMessage) []interface{} {
    var migrations []interface{}
    for _, migration := range rawData {
        // this is an custom struct
        command := UserCommand{}
        json.Unmarshal(migration, &command)
        migrations = append(migrations, command)
    }

    return migrations
}

该代码的问题是:如果我不想解析UserCommand但要解析任何其他产品(例如ProductCommand ,则我必须编写相同的代码,只是在以下行不同: command := UserCommand{} 所以我的问题是:如何通用此代码。

我已经尝试过此解决方案,但是它不起作用:

func parseData(rawData []json.RawMessage, class interface{}) []interface{} {
    var migrations []interface{}
    for _, migration := range rawData {
        command := class
        json.Unmarshal(migration, &command)
        migrations = append(migrations, command)
    }

    return migrations
}
// then I call this method
parseData(data, UserCommand{})

但这是行不通的。 它返回map[string]interface{}数组。如何解决此问题。

编辑:

这是我定义的一些结构

type UserCommand struct {
    User string
    Info string
}
type ProductCommand struct {
    Name      string
    Quanlity  int
}
 // I want to be able to call this method parseData(data, UserCommand{}) 

通过使用Go的reflect包,可以支持这种“通用”签名样式。

package main

import (
    "encoding/json"
    "fmt"
    "reflect"
)

type UserCommand struct {
    User string
    Info string
}

type ProductCommand struct {
    Name     string
    Quantity int
}

func parseData(rawData []json.RawMessage, class interface{}) []interface{} {
    var parsed []interface{}
    for _, elem := range rawData {
        // Create a pointer to a new zero value of the same type as `class`.
        command := reflect.New(reflect.TypeOf(class))
        // Pass a pointer to the new value to `json.Unmarshal`.
        json.Unmarshal(elem, command.Interface())
        // Insert the pointed-to new value into the output slice.
        parsed = append(parsed, command.Elem().Interface())
    }
    return parsed
}

func main() {
    data := []json.RawMessage{
        json.RawMessage(`{"User":"u1","Info":"i1"}`),
        json.RawMessage(`{"User":"u2","Info":"i2"}`),
    }
    parsed := parseData(data, UserCommand{})
    fmt.Printf("%#v\n", parsed)

    data = []json.RawMessage{
        json.RawMessage(`{"Name":"n1","Quantity":1}`),
        json.RawMessage(`{"Name":"n2","Quantity":2}`),
    }
    parsed = parseData(data, ProductCommand{})
    fmt.Printf("%#v\n", parsed)
}

输出显示,第一个parseData调用已解析了两个UserCommand结构,第二个调用已解析了两个ProductCommand结构。

[]interface {}{main.UserCommand{User:"u1", Info:"i1"}, main.UserCommand{User:"u2", Info:"i2"}}
[]interface {}{main.ProductCommand{Name:"n1", Quantity:1}, main.ProductCommand{Name:"n2", Quantity:2}}

暂无
暂无

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

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