比如你是一个go应用,要从一个php的服务获取数据,php是弱类型,很可能会返回(比如透传)1和"1"。
但对于go这样的强类型语言,该如何定义结构体来接收这种不确定类型的响应?
此时可以用encoding/json包里的json.RawMessage类型。具体如下:
package main
import (
"encoding/json"
"fmt"
"reflect"
"strconv"
)
/*
sometimes we don't know what a field's specific value, the value could be 1 or "1",
so how we can define our strongly typed struct ?
json.RawMessage is a good choice.
*/
type MsgCollect struct {
From json.RawMessage `json:"from"`
}
func main() {
str := `{"from":"1"}`
msgCol := &MsgCollect{}
json.Unmarshal([]byte(str), &msgCol)
fmt.Printf("%+v\n", msgCol)
fmt.Println(string(msgCol.From))
fmt.Println("1")
fmt.Println("type: ", reflect.TypeOf(msgCol.From))
// convert to int
fromString := string(msgCol.From)
length := len(fromString)
// trim quotes
fromInt, _ := strconv.Atoi(fromString[1 : length-1])
fmt.Println(fromInt, " , type: ", reflect.TypeOf(fromInt))
// convert to string
fromStr := string(msgCol.From)
fmt.Println(fromStr, " , type: ", reflect.TypeOf(fromStr))
//======================================================
str = `{"from":1}`
//msgCol = &MsgCollect{}
json.Unmarshal([]byte(str), &msgCol)
fmt.Printf("%+v\n", msgCol)
fmt.Println(string(msgCol.From))
fmt.Println("type: ", reflect.TypeOf(msgCol.From))
// convert to int
fromInt, _ = strconv.Atoi(string(msgCol.From))
fmt.Println(fromInt, " , type: ", reflect.TypeOf(fromInt))
// convert to string
fromStr = string(msgCol.From)
fmt.Println(fromStr, " , type: ", reflect.TypeOf(fromStr))
}