Go语言 umarshaling时变换值

ymdaylpp  于 2023-01-06  发布在  Go
关注(0)|答案(1)|浏览(99)

给定下面的代码,是否可以在名字被解组时转换它?假设我希望它总是小写的,不管它是否在实际的json中。

type Person struct {
    FirstName string `json:"first_name"`
    LastName  string `json:"last_name"`
}

func main() {
    jsonText := GetJsonFromSomewhere()
    var v Person
    json.Unmarshal(jsonText, &v)
}
xmjla07d

xmjla07d1#

一种方法是从encoding/json包中创建一个自定义类型来实现Unmarshaler接口。这里有一个到这个接口的链接。任何实现Unmarshaler的类型都可以在进行JSON解组时用作struct字段的类型。在进行解组时,encoding/json将使用接口的UnmarshalJSON函数的实现将JSON字节转换为字段类型。
因此,您可以编写一个UnmarshalJSON函数,其中包括将字符串值更改为小写。
下面是一个可能的示例:

type LowerCaseString string

func (l *LowerCaseString) UnmarshalJSON(bytes []byte) error {
    lowerCasedString := strings.ToLower(string(bytes))

    *l = LowerCaseString(lowerCasedString)

    return nil
}

然后,在JSONMap的结构中,可以使用自定义类型代替string

type Person struct {
    FirstName LowerCaseString `json:"first_name"`
    LastName  LowerCaseString `json:"last_name"`
}

如果您解组到这个结构体中,FirstName和LastName的值将是小写的(还要注意,您需要将它们类型转换回string以将它们用作string)。

testJSON := `{"first_name" : "TestFirstNAME", "last_name": "TestLastNAME"}`
var result Person

err := json.Unmarshal([]byte(testJSON), &result)
if err != nil { /*handle the error*/ }

fmt.Println(result.FirstName) // prints "testfirstname"

var stringLastName string
stringLastName = string(result.LastName) // need to type convert from LowerCaseString to string

fmt.Println(stringLastName) // prints "testlastname"

Here is the above code running in Go Playground.

相关问题