登录
首页 >  Golang >  Go问答

排查与通用类型的 GRPC 响应相关的问题

来源:stackoverflow

时间:2024-02-23 22:09:23 485浏览 收藏

Golang小白一枚,正在不断学习积累知识,现将学习到的知识记录一下,也是将我的所得分享给大家!而今天这篇文章《排查与通用类型的 GRPC 响应相关的问题》带大家来了解一下##content_title##,希望对大家的知识积累有所帮助,从而弥补自己的不足,助力实战开发!


问题内容

我正在尝试使用泛型将 json 对象转换为具有枚举的 grpc 响应,即:

type grpcresponse {
    str string
    enu enumtype
}

type enumtype int32
const (
    type1 enumtype = 0
    type2 enumtype = 1
)

解组函数如下所示:

func asserthttpresponseok[t any](t *testing.t, endpoint string) t {
    body, err := getresponse(endpoint)

    var v t
    err := json.unmarshal(body, &v)
    require.nil(t, err)
    return v
}

调用它的代码如下所示:

asserthttpresponseok[*grpcresponse](t, "some-endpoint")

相关的 json 对象如下所示:

{"str":"hello", "enu": "type2"}

我收到了一个错误:

json: cannot unmarshal string into Go struct field GRPCResponse.enu of type EnumType

从类似的问题中,我发现通常的建议是使用 jsonpb.unmarshalprotojson.unmarshal 而不是典型的 json.unmarshal

在更改 unmarshal 函数时,我还必须将 t 更改为 protoreflect.protomessage。但是,这阻止我将指向 v 的指针传递给 unmarshal,因为它是指向接口的指针,而不是接口。当然,我也不能传入一个nil指针(不取v的地址)。

所以我的问题是:

  1. 有没有办法让这个泛型对象的指针满足接口protoreflect.protomessage
  2. 是否有更好的解组函数更适合我的问题?

正确答案


我最终传入了我要解组的对象。

obj := new(grpcresponse)
asserthttpresponseok[*grpcresponse](t, ctx, "some-endpoint", obj)
func asserthttpresponseok[t protoreflect.protomessage](t *testing.t, ctx context.context, endpoint string, object t) {
    body, err := getresponse(endpoint)
    require.nil(t, err)

    err = protojson.unmarshal(body, object)
    require.nil(t, err)
}

这是一个泛型友好的原型解组器,它避免传递第二个类型,但代价是反射调用以查看指针内的类型并调用其构造函数。

var msg T // Constrained to proto.Message

        // Peek the type inside T (as T= *SomeProtoMsgType)
        msgType := reflect.TypeOf(msg).Elem()

        // Make a new one, and throw it back into T
        msg = reflect.New(msgType).Interface().(T)

        errUnmarshal := proto.Unmarshal(body, msg)

文中关于的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《排查与通用类型的 GRPC 响应相关的问题》文章吧,也可关注golang学习网公众号了解相关技术文章。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>