Go泛型:如何在switch中将已知类型转为类型参数的指针?
问题:泛型函数中如何将[]byte指针赋值给泛型返回值?
需求是实现一个泛型函数,根据返回值的类型参数规则,将JSON字节数组转换为对应类型,规则如下:
- 若类型参数为
map[string]interface{}:转换为对应map类型 - 若类型参数为
[]byte:直接返回原字节数组,不做JSON解析 - 若类型参数为结构体:转换为对应结构体实例
当前编写的代码如下:
func GetJsonData[T any](jsonByteArray []byte) (result *T, err error) { var buff T switch any(result).(type) { case *[]byte: result = &T(jsonByteArray) default: err = json.Unmarshal(jsonByteArray, &buff) result = &buff } return }
这段代码在编译时报错,错误信息:
cannot convert jsonByteArray (variable of type []byte) to type T
需要解决的问题是:如何在泛型函数中,将[]byte类型变量的指针正确赋值给泛型类型的返回值?
解决方案
原代码的核心问题在于:泛型参数T是任意类型,编译器无法直接确认T与[]byte的类型兼容关系,因此直接使用T(jsonByteArray)进行强制转换是不合法的。需要通过类型断言来明确类型后再进行赋值操作。
修正后的代码
import "encoding/json" func GetJsonData[T any](jsonByteArray []byte) (result *T, err error) { var buff T // 判断当前泛型类型T是否为[]byte if bytesPtr, ok := any(&buff).(*[]byte); ok { // 确认类型后直接赋值原字节数组 *bytesPtr = jsonByteArray result = &buff return } // 其他类型执行JSON反序列化 err = json.Unmarshal(jsonByteArray, &buff) result = &buff return }
代码说明
- 类型断言判断:通过
any(&buff).(*[]byte)断言buff的指针是否为*[]byte类型,以此确认泛型参数T是否为[]byte。 - 直接赋值原数组:若断言成功,直接将输入的
jsonByteArray赋值给buff(通过指针修改其值),避免不必要的JSON解析。 - 通用反序列化逻辑:对于其他类型(如map、结构体),正常调用
json.Unmarshal完成转换。
另一种实现方式(使用switch判断)
如果更倾向于用switch语法,也可以这样写:
import "encoding/json" func GetJsonData[T any](jsonByteArray []byte) (result *T, err error) { var buff T switch any(buff).(type) { case []byte: // 断言buff的指针为*[]byte并赋值 if b, ok := any(&buff).(*[]byte); ok { *b = jsonByteArray } result = &buff default: err = json.Unmarshal(jsonByteArray, &buff) result = &buff } return }
内容的提问来源于stack exchange,提问作者Ueda Takeyuki
相关产品推荐
相关产品推荐

