为了账号安全,请及时绑定邮箱和手机立即绑定

空接口是绕过类型系统的一种方式吗?

空接口是绕过类型系统的一种方式吗?

Go
慕妹3242003 2022-08-24 20:32:31
我正在学习Go(来自Python),强制打字系统实际上很有帮助。我对的了解非常有限,导致我使用以下代码,其中我从API检索JSON数据并返回解析版本。结果可以是对象或对象列表。interface{}func getJsonFromApi(endpoint string) (reply interface{}, err error) {    res, err := http.Get("http://127.0.0.42/api/" + endpoint)    if err != nil {        return nil, err    }    body, err := ioutil.ReadAll(res.Body)    err = res.Body.Close()    if err != nil {        return nil, err    }    err = json.Unmarshal(body, &reply)    return reply, nil}它有效,但我通过颠覆类型系统感到不舒服。这是 的预期用法吗?interface{}我最终会将代码更改为始终返回一个对象数组(并在我的第一个用例中获取第一个对象),但我对一般问题感到好奇。
查看完整描述

2 回答

?
慕莱坞森

TA贡献1810条经验 获得超4个赞

如果可能,最好使用 .您可以使用 :structmap


package main


import (

   "encoding/json"

   "net/http"

)


func main() {

   r, e := http.Get("https://github.com/manifest.json")

   if e != nil {

      panic(e)

   }

   defer r.Body.Close()

   m := make(map[string]interface{})

   json.NewDecoder(r.Body).Decode(&m)

   s := m["icons"].([]interface{})[0].(map[string]interface{})["sizes"].(string)

   println(s == "114x114")

}

但是正如你所看到的,当你需要解开包装以获得实际价值时,它会变得非常痛苦。 好多了:struct


package main


import (

   "encoding/json"

   "net/http"

)


func main() {

   r, e := http.Get("https://github.com/manifest.json")

   if e != nil {

      panic(e)

   }

   defer r.Body.Close()

   var m struct {

      Icons []struct { Sizes string }

   }

   json.NewDecoder(r.Body).Decode(&m)

   s := m.Icons[0].Sizes

   println(s == "114x114")

}


查看完整回答
反对 回复 2022-08-24
?
慕标5832272

TA贡献1966条经验 获得超4个赞

空接口 是指定零个方法的接口。它可以保存任何类型的值(https://tour.golang.org/methods/14),因此它是您在不知道实际类型的情况下用来保存某些内容的类型。interface{}

在像您这样的示例中,有时这是必要的,但代价是强类型化。我不认为你应该在你的例子中使用它感到不舒服,但是如果它最终到处都是,你应该开始感到不舒服。

您可以允许方法的调用方传入实际类型,如果您改用此签名:

func getJsonFromApi(endpoint string, reply interface{}) (err error) {

我会说它是类型系统的一部分,而不是绕过它的方法。


查看完整回答
反对 回复 2022-08-24
  • 2 回答
  • 0 关注
  • 70 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信