doudong2149 2015-11-25 12:03
浏览 68
已采纳

Go-将泛型结构传递给函数

Considering the following code, which is responding to GET '/venues/:id':

func venueShow(w http.ResponseWriter, req *http.Request) {

  // get ID from params
  vars := mux.Vars(req)
  id := vars["id"]

  // initialise new struct
  var venue Venue

  // select by id and scan into struct
  db.First(&venue, id).Scan(&venue)

  // turn it to json
  response := structToJSON(&venue)

  // write headers and provide response
  w.Header().Set("Content-Type", "application/json")
  w.Write(response)
}

and:

func structToJSON (s interface{}) (response []byte) {
  // turn it into pretty-ish json
  response, err := json.MarshalIndent(&s, "", "  ")
  if err != nil {
   return []byte("Venue does not exist")
  }
  // return the json as the reponse
  return response
}

My structToJSON function is taking an empty interface as the argument, because I want to pass various different structs to the function and have them spewed out as JSON.

However, it doesn't strike me as very safe. If anything satisfies an empty interface, I could pass whatever I wanted into that function, and all sorts of errors might happen when json.Marshal tries to do it's business. This (I suppose) would be caught by the compiler rather than at runtime, but is there a safer way?

I could duplicate the structToJSON method for each different type of Struct/Model that I pass to it, but that's not very DRY.

Thanks

  • 写回答

1条回答 默认 最新

  • dongwan0574 2015-11-25 12:24
    关注

    The Marshal function also receives its parameters as interface{} therefore there's no way to detect if you are passing something invalid at compile time, it's all caught at runtime.

    One thing you can do to check if an invalid type was passed to Marshal is to check the error type, Marshal returns an UnsupportedTypeError when you try to Marshal an invalid type (like chan or func) so you can check for that error when Marshaling.

    So you could try something like that:

    if err != nil {
        _, ok := err.(*json.UnsupportedTypeError)
        if ok {
            return []byte("Tried to Marshal Invalid Type")
        } else {
            return []byte("Venue does not exist")
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 目详情-五一模拟赛详情页
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 unity第一人称射击小游戏,有demo,在原脚本的基础上进行修改以达到要求
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b