【问题标题】:How to use a reflect.Type to perform a type assertion如何使用 reflect.Type 执行类型断言
【发布时间】:2018-02-26 15:21:43
【问题描述】:

我知道在 go 中反射通常是不受欢迎的,但就我目前的目的而言,我很确定这是最好的解决方案。

基本上我的项目是cli工具,它将根据传入的命令输出一个xml查询并返回相应的结果。

每个命令请求都有一些样板代码,其中填充了默认值并验证了提供的值。

所以我有一系列基于 Command 结构的 Command 对象,如下所示:

type Command struct {
    Name        string
    Request     interface{}
    RequestType reflect.Type
    Response    interface{}

    RegisterFunc func(parentCmd *cobra.Command, cmd *Command) error
}

在大多数情况下,我真的不关心请求/响应的类型(只是 xml 编码/解码)。但是我需要将其简要转换为具体类型以使用结构注释进行验证 所以例如我可能会做这样的事情:

    var ccReq *CreateCredentialRequest
    var set bool
    if ccReq, set = command.Request.(*CreateCredentialRequest); !set {
        log.Fatal(errors.New("invalid request type"))
    }

    result, err := govalidator.ValidateStruct(ccReq)
    if err != nil {
        println("error: " + err.Error())
        os.Exit(1)
    }

但在理想情况下,我希望对所有命令进行通用处理,如下所示:

    var ccReq *CreateCredentialRequest
    var set bool
    if ccReq, set = command.Request.(command.RequestType); !set {
        log.Fatal(errors.New("invalid request type"))
    }

但是这会导致错误:

command.RequestType 不是类型

那么,如何存储类型的值以供以后的类型断言使用

注意:在 cmets 与 JimB 的讨论之后,我似乎实际上不需要具体类型来进行验证(接口很好),但我仍然需要进一步断言响应类型以提供自定义响应处理程序

【问题讨论】:

    标签: go reflection


    【解决方案1】:

    来自reflect.Type docs

    类型值是可比较的,例如使用 == 运算符,因此它们可以用作映射键。如果两个 Type 值表示相同的类型,则它们是相等的。

    如果要比较底层类型,直接比较reflect.Type的值:

    if reflect.TypeOf(command.Request) != command.RequestType {
        log.Fatal(errors.New("invalid request type"))
    }
    

    【讨论】:

    • 谢谢,这解决了我的部分问题,但我还需要处理原始请求类型来运行验证,我如何才能使用 reflect.Type 实际执行类型断言
    • @WebweaverD:“实际执行类型断言”是什么意思?你到底想用ccReq 值做什么?
    • 我需要验证它 - 我在原始类型上使用结构注释来定义验证规则,因此需要 govalidator 包的具体类型 - 见行'result, err := govalidator.ValidateStruct( ccReq)',类型的验证只是为了很好的衡量
    • ValidateStruct 接受interface{},您无需断言或转换任何内容即可将command.Request 传递给它。
    • 啊,好地方,谢谢 - 所以我实际上不需要它来达到这个目的,但就我当前的代码而言,我仍然需要它来进一步向下响应处理程序(抱歉,我认为不包括在问题中)不相关) - 可能我可以通过重新思考代码来避免这种情况,但你知道我问的是否可能 - 从 reflect.Type 和接口制作具体类型
    猜你喜欢
    • 2019-05-23
    • 1970-01-01
    • 2010-12-09
    • 2015-03-10
    • 2020-10-15
    • 1970-01-01
    • 2019-12-26
    • 2022-07-23
    • 2019-06-07
    相关资源
    最近更新 更多