简体   繁体   English

Go - 将通用结构传递给函数

[英]Go - passing generic struct to function

Considering the following code, which is responding to GET '/venues/:id': 考虑以下代码,它响应GET'/场所/: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. 我的structToJSON函数将空接口作为参数,因为我想将各种不同的结构传递给函数并将它们作为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. 如果有任何东西满足空接口,我可以将任何我想要的东西传递给该函数,并且当json.Marshal试图做它的业务时可能会发生各种错误。 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. 我可以为我传递给它的每种不同类型的Struct / Model复制structToJSON方法,但这不是很干。

Thanks 谢谢

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. Marshal函数也接收它作为interface{}参数,因此没有办法检测你是否在编译时传递了一些无效的东西,它们都是在运行时捕获的。

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. 检查是否将无效类型传递给Marshal的一件事是检查错误类型,当您尝试将无效类型(如chanfuncUnsupportedTypeError时,Marshal会返回UnsupportedTypeError ,以便您可以在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")
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM