英文:
cannot use type interface {} as type person in assignment: need type assertion
问题
我尝试将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 // 错误发生在这里 -------------------------------
// -------------- 类型断言总是给我 '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
。
英文:
I try to convert interface{}
to 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)
// }
}
... But got error:
cannot use type interface {} as type person in assignment: need type assertion
To solve this error I tried to use type assertion actual, ok := actualInterface.(person)
but always got not ok
.
Playground link
答案1
得分: 6
处理这个问题的常见方法是将指向输出值的指针传递给解码辅助函数。这样可以避免在应用程序代码中进行类型断言。
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)
}
英文:
The usual way to handle this is to pass a pointer to the output value to your decoding helper function. This avoids type assertions in your application code.
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
得分: 5
你的问题在于你一开始创建了一个空接口,并告诉json.Unmarshal
将其解组为该接口。虽然你定义了一个person
类型,但json.Unmarshal
无法知道你打算将JSON的类型设为什么。要解决这个问题,将person
的定义移到顶层(也就是将其移出main
函数的主体),并将FromJson
函数修改为以下内容:
func FromJson(jsonSrc string) interface{} {
var obj person{}
json.Unmarshal([]byte(jsonSrc), &obj)
return obj
}
现在,当你返回obj
时,返回的interface{}
类型的对象的底层类型是person
。你可以在Go Playground上运行这段代码。
顺便说一下,你的代码有点不符合惯例。我只对原始的Playground链接进行了修改,除了我所做的更正之外,没有其他不必要的混淆。如果你感兴趣,这里有一个版本进行了清理,更符合惯例(包括对我所做更改的注释)。
英文:
Your problem is that you're creating an empty interface to begin with, and telling json.Unmarshal
to unmarshal into it. While you've defined a person
type, json.Unmarshal
has no way of knowing that that's what you intend the type of the JSON to be. To fix this, move the definition of person
to the top level (that is, move it out of the body of main), and change
FromJson` to this:
func FromJson(jsonSrc string) interface{} {
var obj person{}
json.Unmarshal([]byte(jsonSrc), &obj)
return obj
}
Now, when you return obj
, the interface{}
that's returned has person
as its underlying type. You can run this code on the Go Playground.
By the way, your code is a bit un-idiomatic. I left the original Playground link unmodified except for my corrections so that it wouldn't be needlessly confusing. If you're curious, here's a version that's cleaned up to be more idiomatic (including comments on why I made the changes I did).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论