如何将已知类型转换为指向开关中类型参数的指针?

Ued*_*uki 3 generics go

我正在尝试编写一个函数,根据返回值的类型参数将 JSON 字符串的字节数组转换为另一个字节数组,规则如下:

  • map[string]interface{}:转换为map[string]interface{}
  • []byte:不转换,按原样返回
  • 结构体:转换为结构体

我的代码如下:

func GetJsonData[T any](jsonByteArray []byte) (result *T, err error) {
    var buff T

    switch any(result).(type) { // https://appliedgo.com/blog/a-tip-and-a-trick-when-working-with-generics
    case *[]byte:
        result = &T(jsonByteArray)
    default:
        err = json.Unmarshal(jsonByteArray, &buff)
        result = &buff
    }

    return
}
Run Code Online (Sandbox Code Playgroud)

此代码在将jsonByteArray 的类型转换为 T 时发生类型错误,如下所示:

cannot convert jsonByteArray (variable of type []byte) to type T
Run Code Online (Sandbox Code Playgroud)

如何将这个[]byte类型变量的指针赋给泛型类型返回值?

bla*_*een 5

由于T受 约束any,因此可以\xe2\x80\x99t 直接转换。您必须断言它与该 switch 案例中的&jsonByteArray类型确实相同:*T

\n
func GetJsonData[T any](jsonByteArray []byte) (result *T, err error) {\n    var buff T\n\n    switch any(result).(type) {\n    case *[]byte:\n        result = any(&jsonByteArray).(*T)\n    default:\n        err = json.Unmarshal(jsonByteArray, &buff)\n        result = &buff\n    }\n\n    return\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这使得编译错误消失,但是它不是特别好的设计。如果您只需要专门json.Unmarshal针对一种类型 ( *[]byte),您最好更改调用站点,而不是使用通用函数。

\n

我假设您的目标是允许调用者按原样获取字节切片,而不是解组。然后在调用站点您可以将该函数调用为

\n
data := GetJsonData[[]byte](jsonByteArray)\n
Run Code Online (Sandbox Code Playgroud)\n

这意味着此时您已经知道jsonByteArray是一个字节切片。

\n

那么,\xe2\x80\x99s 没有理由调用该函数。您可以简单地获取参数的地址:data := &jsonByteArray,并json.Unmarshal在其他地方使用。

\n