我尝试将interface{}
转换为struct 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
。
答案 0 :(得分:5)
处理此问题的常用方法是将指向输出值的指针传递给解码辅助函数。这可以避免应用程序代码中的类型断言。
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)
}
答案 1 :(得分:3)
您的问题是,您要创建一个空的界面,然后告诉json.Unmarshal
解组它。虽然您已经定义了person
类型,但json.Unmarshal
无法知道您希望JSON的类型是什么。要解决此问题,请将person
的定义移至顶层(即将其移出main), and change
FromJson`的主体:
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已经清理得更加惯用(包括我为何做出更改的评论)。