英文:
Reading a signed value into an unsigned type
问题
在Go语言中,可以通过以下方式将有符号值强制解释为无符号值:
var x int32
var y uint32
x = -1
y = uint32(x)
这段代码的作用是将x
的值解释为无符号的uint32类型,并将结果赋给y
。这样做可以得到预期的结果,y
将取得最大的无符号int32值。然而,如果我有一个JSON字符串,如下所示:
注意:似乎无论值-20
是作为字符串还是作为数字序列化,都没有关系
jsonStr := `{"RandomNumber": -20}`
type DummyJson struct {
RandomNumber uint32
}
rd := &DummyJson{}
err := json.Unmarshal([]byte(jsonStr), &rd)
fmt.Println(err)
在这里,它会报错,因为无法将值-20反序列化到RandomNumber字段中。我该如何说服Go将有符号值强制转换为无符号类型?
附注:这样做的动机很复杂和曲折。所以请假设这个问题背后有一个合理的原因。
英文:
In Go, one can take a signed value and force the language to interpret it as unsigned by doing something like:
var x int32
var y uint32
x = -1
y = uint32(x)
This works as expected with y
taking the largest unsigned int32 value. However, if I have a JSON string like so:
Note: it doesn't seem to matter if the value -20
is serialized as a string or as a number
jsonStr := `{"RandomNumber: -20}
type DummyJson struct {
RandomNumber uint32
}
rd := &DummyJson{}
err := json.Unmarshal([]byte(jsonStr), &rd)
fmt.Println(err)
Here, it complains the value -20 cannot be unmarshaled into the RandomNumber field. How can I convince Go to shove the signed value into an unsigned type?
P.S: The motivation for doing this is long and convoluted. So please assume there is a legitimate reason behind this question.
答案1
得分: 1
创建具有UnmarshalJSON
方法的自定义类型。
type DummyJson struct {
RandomNumber CustomIntType
}
type CustomIntType uint32
func (ct *CustomIntType) UnmarshalJSON(b []byte) error {
var x int32
var y uint32
s := string(b)
if i, err := strconv.Atoi(s); err == nil {
x = int32(i)
y = uint32(x)
*ct = CustomIntType(y)
} else {
return err
}
return nil
}
jsonStr := `{"RandomNumber": -20}`
var rd DummyJson
err := json.Unmarshal([]byte(jsonStr), &rd)
fmt.Println(rd.RandomNumber, err)
我确定可以优化转换,但不确定如何优化。
英文:
Create custom type with UnmarshalJSON
method.
type DummyJson struct {
RandomNumber CustomIntType
}
type CustomIntType uint32
func (ct *CustomIntType) UnmarshalJSON(b []byte) error {
var x int32
var y uint32
s := string(b)
if i, err := strconv.Atoi(s); err == nil {
x = int32(i)
y = uint32(x)
*ct = CustomIntType(y)
} else {
return err
}
return nil
}
jsonStr := `{"RandomNumber": -20}`
var rd DummyJson
err := json.Unmarshal([]byte(jsonStr), &rd)
fmt.Println(rd.RandomNumber, err)
I am sure that the conversion can be optimised, but not sure how.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论