【问题标题】:Golang - Handling situations that would require generic typesGolang - 处理需要泛型类型的情况
【发布时间】:2019-03-06 22:06:45
【问题描述】:

我为我的 API 编写了一个 sendError 处理程序,它将接受一个字符串并向我的 HTTP 服务器返回一个响应。函数如下:

func sendError(code string, message string, trace error, status int) (Response) {
  body, err := json.Marshal(&struct{
    Code    string `json:"Code"`
    Message string `json:"Message"`
  }{
    Code: code,
    Message: message,
  })
  fmt.Println(trace)
  if err != nil {
    panic("Issue parsing an error msg?")
  }
  return Response{
    Body: string(body),
    StatusCode: status,
    Headers: map[string]string{
      "Content-Type": "application/json",
    },
  }
}

很简单,对吧?但是最近我不得不返回更高级的消息类型。基本上是来自我的支持库 (https://godoc.org/github.com/go-ozzo/ozzo-validation#ValidateStruct) 的验证错误的哈希图(或字典)。我目前正在做的是:

err := account.Validate()
if err != nil {
  fmt.Println(err)
  message, err := json.Marshal(err)
  return sendError(
    "VALIDATION_ERROR", string(message), err, 400,
  ), nil
}

但是,正如你所知道的,它基本上会返回类似于:

{
    "Code": "VALIDATION_ERROR",
    "Message": "{\"Email\":\"must be a valid email address\"}"
}

被封送的 JSON 显然被序列化到响应中的 Message 属性中。我可以轻松地添加另一个参数来处理接受字典的情况,并简单地扩展错误响应以具有附加字段(因此几乎全部编组)。为了使我的 sendError 函数更符合人体工程学,并查看这样的泛型是否可行。我想将消息更改为通用值,即。 interface{} 并根据条件检查决定处理字典或响应的字符串版本。

在这种情况下最好/最合适的方法是什么?

【问题讨论】:

    标签: go


    【解决方案1】:

    使用类型interface{} 作为消息参数和消息字段:

    func sendError(code string, message interface{}, trace error, status int) (Response) {
      body, err := json.Marshal(&struct{
        Code    string      `json:"Code"`
        Message interface{} `json:"Message"`
      }{
        Code: code,
        Message: message,
      })
      fmt.Println(trace)
      if err != nil {
        panic("Issue parsing an error msg?")
      }
      return Response{
        Body: string(body),
        StatusCode: status,
        Headers: map[string]string{
          "Content-Type": "application/json",
        },
      }
    }
    

    通过此更改,应用程序可以使用 string 或任何其他可编组为 JSON 的值调用函数。例如,这样称呼它:'

    err := account.Validate()
    if err != nil {
      fmt.Println(err)
      return sendError("VALIDATION_ERROR", err, err, 400), nil
    }
    

    (这个 sn-p 假设 err 以合适的方式编组为 JSON。根据问题中的信息,它看起来确实如此)。

    【讨论】:

    • 这实际上和我想象的一样简单。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2017-11-25
    • 1970-01-01
    • 2017-01-26
    • 1970-01-01
    • 2014-04-13
    • 2022-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多