将有符号值读入无符号类型

huangapple go评论81阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2021年10月12日 06:00:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/69532909.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定