总是将JSON解组为特定类型(字符串)
我有一些JSON,第一个元素可以是数字或字符串。我总是希望能够将其存储为字符串值,但相反,我得到了一个崩溃,因为它读取的结果与数字类型一样正确 我试图强制将解组作为字符串,但没有成功总是将JSON解组为特定类型(字符串),json,go,unmarshalling,Json,Go,Unmarshalling,我有一些JSON,第一个元素可以是数字或字符串。我总是希望能够将其存储为字符串值,但相反,我得到了一个崩溃,因为它读取的结果与数字类型一样正确 我试图强制将解组作为字符串,但没有成功 string `json:",string"` 我正在遵循这一点,这似乎很符合我的数据 如何始终使[0]处的此元素始终读取并保存为字符串 下面是代码和操场 您可以创建一个通用接收器,即接口类型,然后执行类型断言: package main import ( "encoding/json" "f
string `json:",string"`
我正在遵循这一点,这似乎很符合我的数据
如何始终使[0]处的此元素始终读取并保存为字符串
下面是代码和操场
您可以创建一个通用接收器,即接口类型,然后执行类型断言:
package main
import (
"encoding/json"
"fmt"
)
type RawMessage struct {
UnknownType interface{} `json:"unknown_type"`
}
const inputString = `{"unknown_type" : "a"}`
const inputFloat = `{"unknown_type" : 123}` // Note: Unmarshals into a float64 by default!!!
func main() {
var n RawMessage
if err := json.Unmarshal([]byte(inputFloat), &n); err != nil {
println(err.Error())
}
switch v := n.UnknownType.(type) {
case string:
fmt.Printf("Received a string: %v", v)
case float64:
fmt.Printf("Received a number: %v", v)
default:
fmt.Printf("Unknown type: %v", v)
}
}
如果解决了此问题,请尝试此操作,因为未定义用户输入,请创建一个通用接口
interface{} `json:",string"`
包干管
import "fmt"
import "log"
import "encoding/json"
const inputWorking = `
["AAAAAA", {"testcode" : "Sss"}, 66666666]
`
const inputBroken = `
[111111, {"testcode" : "Sss"}, 66666666]
`
type RawMessage struct {
AlwaysString interface{} `json:",string"`
ClientData ClientData
ReceptionTime int
}
type ClientData struct {
testcode string
}
func main() {
var n RawMessage
if err := json.Unmarshal([]byte(inputWorking), &n); err != nil {
log.Fatal(err)
}
fmt.Printf("%#v\n", n)
var o RawMessage
if err := json.Unmarshal([]byte(inputBroken), &o); err != nil {
log.Fatal(err)
}
我也遇到了同样的问题,到目前为止,我发现最好的方法是使用自定义解组器从字符串生成类型:
package main
import (
"encoding/json"
"fmt"
"strconv"
)
// Stringish exists because api send back integers unquoted even if underlying type is string
type StringIsh string
func (f *StringIsh) UnmarshalJSON(data []byte) error {
var receiver string
if len(data) == 0 {
return nil
}
if data[0] != '"' {
quoted := strconv.Quote(string(data))
data = []byte(quoted)
}
if err := json.Unmarshal(data, &receiver); err != nil {
return err
}
*f = StringIsh(receiver)
return nil
}
type Test struct {
Foo StringIsh
}
func main() {
dest := &Test{}
_ = json.Unmarshal([]byte(`{"foo": "bar"}`), &dest)
fmt.Println(dest)
dest = &Test{}
_ = json.Unmarshal([]byte(`{"foo": 123}`), &dest)
fmt.Println(dest)
}
你自己试试吧啊,当然可以!所以有点像。。。每当我读取这个值时,我都会确保检查它?@LeeArmstrong,是的-你把它放到接口{}中,然后断言它是字符串还是数字。请记住,Go不会在接收时区分整型和浮点型,它只会为所有内容提供浮点64。因此,如果需要的话,您可能还需要将其转换为int。这与上面的方法没有什么不同,并且不会另存为字符串
package main
import (
"encoding/json"
"fmt"
"strconv"
)
// Stringish exists because api send back integers unquoted even if underlying type is string
type StringIsh string
func (f *StringIsh) UnmarshalJSON(data []byte) error {
var receiver string
if len(data) == 0 {
return nil
}
if data[0] != '"' {
quoted := strconv.Quote(string(data))
data = []byte(quoted)
}
if err := json.Unmarshal(data, &receiver); err != nil {
return err
}
*f = StringIsh(receiver)
return nil
}
type Test struct {
Foo StringIsh
}
func main() {
dest := &Test{}
_ = json.Unmarshal([]byte(`{"foo": "bar"}`), &dest)
fmt.Println(dest)
dest = &Test{}
_ = json.Unmarshal([]byte(`{"foo": 123}`), &dest)
fmt.Println(dest)
}