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

我正在学习 Go(来自 Python)并且强制输入系统实际上很有帮助。我interface{}对以下代码的理解非常有限,我在其中从 API 检索 JSON 数据并返回解析后的版本。结果可以是一个对象或一个对象列表。

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{}吗?

我最终将更改代码以始终返回一个对象数组(并在我的第一个用例中获取第一个对象),但我对一般问题感到好奇。

回答

如果可能,最好使用struct. 您可以使用map

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")
}


以上是空接口是一种绕过类型系统的方法吗?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>