使用泛型将结构转换为映射

问题描述 投票:0回答:1

我一直在尝试使用如下泛型将结构转换为映射

// You can edit this code!
// Click here and start typing.
package main

import (
    "encoding/json"
    "fmt"
)

type Data interface {
    int64 | float64 | string
}

type Server struct {
    Name    string
    ID      int32
    Enabled bool
}

func ConvertStructToMap[K comparable, V Data](in interface{}) map[string]V {
    var inInterface map[string]V
    inrec, _ := json.Marshal(in)
    json.Unmarshal(inrec, &inInterface)
    return inInterface

}

func main() {

    s := &Server{
        Name:    "gopher",
        ID:      123456,
        Enabled: true,
    }
    conv := ConvertStructToMap(s)
    fmt.Println(conv)

}

但是它给了我一个错误

无法推断 K (prog.go:20:25)

我刚刚开始使用 go generics,我想要的是使用泛型将结构转换为映射。任何帮助将不胜感激

go generics
1个回答
-1
投票

虽然 golang 有泛型,但你正在尝试创建一个泛型映射,据我所知,这是行不通的:推断的类型必须是其中一种类型:

例如输入 3 种不同类型,对

string
int64
float64
的严格返回映射的推断不起作用,您必须向编译器提供额外信息。
or
是文档中的重要单词(请参阅入门指南 https://go.dev/doc/tutorial/generics

package main

import (
    "encoding/json"
    "fmt"
)

type Data interface {
    int64 | float64 | string
}

type Server struct {
    Name    string
    ID      int32
    Enabled bool
}

func ConvertStructToMap[V Data](in interface{}) map[string]V {
    var inInterface map[string]V
    inrec, _ := json.Marshal(in)
    json.Unmarshal(inrec, &inInterface)
    return inInterface

}

func main() {

    s := &Server{
        Name:    "gopher",
        ID:      123456,
        Enabled: true,
    }
    conv := ConvertStructToMap[int64](s)
    fmt.Println(conv)
}

因此,使用泛型,除非您只想解析出 1 种类型,否则您将无法到达您想要的位置。仍然进行类型检查(评论中提到的反思)效果会更好。

替代方案:

json.RawMessage

如果您定义了

map[string]json.RawMessage
,您可以使用它来进一步解码信息,方法是使用反射、e.(type) 或泛型对每个元素进行单独调用来解析该类型。您可能仍然会遇到推理问题,在这种情况下,可能需要使用
json.RawMessage
而不是
map[string]interface{}

© www.soinside.com 2019 - 2024. All rights reserved.