【问题标题】:cannot use type interface {} as type person in assignment: need type assertion不能在赋值中使用 type interface {} 作为类型 person:需要类型断言
【发布时间】:2014-12-12 04:48:45
【问题描述】:

我尝试将interface{} 转换为结构person...

package main

import (
    "encoding/json"
    "fmt"
)

func FromJson(jsonSrc string) interface{} {
    var obj interface{}
    json.Unmarshal([]byte(jsonSrc), &obj)

    return obj
}

func main() {

    type person struct {
        Name string
        Age  int
    }
    json := `{"Name": "James", "Age": 22}`

    actualInterface := FromJson(json)

    fmt.Println("actualInterface")
    fmt.Println(actualInterface)

    var actual person

    actual = actualInterface // error fires here -------------------------------

    // -------------- type assertion always gives me 'not ok'
    // actual, ok := actualInterface.(person)
    // if ok {

    //  fmt.Println("actual")
    //  fmt.Println(actual)
    // } else {
    //  fmt.Println("not ok")
    //  fmt.Println(actual)
    // }
}

...但出现错误:

cannot use type interface {} as type person in assignment: need type assertion

为了解决这个错误,我尝试使用类型断言actual, ok := actualInterface.(person),但总是得到not ok

Playground link

【问题讨论】:

    标签: go


    【解决方案1】:

    处理此问题的常用方法是将指向输出值的指针传递给解码辅助函数。这避免了应用程序代码中的类型断言。

    package main
    
    import (
        "encoding/json"
        "fmt"
    )
    
    func FromJson(jsonSrc string, v interface{}) error {
        return json.Unmarshal([]byte(jsonSrc), v)
    
    }
    
    func main() {
        type person struct {
            Name string
            Age  int
        }
        json := `{"Name": "James", "Age": 22}`
    
        var p person
        err := FromJson(json, &p)
    
        fmt.Println(err)
        fmt.Println(p)
    }
    

    【讨论】:

      【解决方案2】:

      您的问题是您开始创建一个空接口,并告诉json.Unmarshal 解组到它。虽然您已经定义了 person 类型,但 json.Unmarshal 无法知道这就是您想要的 JSON 类型。要解决此问题,请将person 的定义移至顶层(即,将其移出main), and changeFromJson` 的主体至此:

      func FromJson(jsonSrc string) interface{} {
          var obj person{}
          json.Unmarshal([]byte(jsonSrc), &obj)
      
          return obj
      }
      

      现在,当您返回 obj 时,返回的 interface{}person 作为其基础类型。您可以在Go Playground 上运行此代码。

      顺便说一句,您的代码有点不习惯。除了我的更正之外,我没有修改原始的 Playground 链接,以免造成不必要的混乱。如果您好奇,here's a version 已被清理为更惯用的方式(包括 cmets 关于我为什么做出更改的原因)。

      【讨论】:

        猜你喜欢
        • 2018-06-28
        • 1970-01-01
        • 1970-01-01
        • 2021-12-10
        • 2020-07-25
        • 1970-01-01
        • 2019-09-02
        • 2022-08-09
        • 1970-01-01
        相关资源
        最近更新 更多