例如,我想写一个这样的方法:
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
之类的任何其他代码,我必须编写相同的代码,但只有不同的代码:{{ 1}}。所以我的问题是:我如何通用这个代码。
我尝试过这个解决方案,但它不起作用:
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{}
答案 0 :(得分:1)
class X { apples(){ return "apples"; } pears(){ return "pears"; } lemons(){ return "lemons"; } // We use a genric function to ensure the type of values is a union on literal types not string static readonly values = (<T extends string>(v: T[]) => v)(['apples', 'pears', 'lemons']) callFunction (type: string){ const index = X.values.indexOf(type as any); //If the value is not in the expected input we raise an error if(index == -1) throw "Value not ok"; // Since values[index] is a union of apples | pears | lemons // the type of this[X.values[index]] will be ()=> string // inferred based on return this[X.values[index]](); } }
可以支持这种&#34;泛型&#34;使用Go的reflect
包进行签名。
// I want to be able to call this method
parseData(data, UserCommand{})
输出显示第一个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