你可以通过检查字段是否为null来确定字段是否被设置为null。

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

How can I know that the field is set to null?

问题

我想要在 JSON 字段包含 null 值时输出一个错误。我该如何做呢?我已经尝试了 "encoding/json" 包,也许我需要另一个库。

代码示例:

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "strings"
  6. )
  7. type Item struct {
  8. Value *int
  9. }
  10. func main() {
  11. var jsonBlob = `[
  12. {},
  13. {"Value": null},
  14. {"Value": 0},
  15. {"Value": 1}
  16. ]`
  17. var items []Item
  18. err := json.NewDecoder(strings.NewReader(jsonBlob)).Decode(&items)
  19. if err != nil {
  20. fmt.Println("error:", err)
  21. }
  22. for _, a := range items {
  23. if a.Value != nil {
  24. fmt.Println(*a.Value)
  25. } else {
  26. fmt.Println("<error>")
  27. }
  28. }
  29. }

我得到的输出是:

  1. <nil>
  2. <nil>
  3. 0
  4. 1

我想要的输出是:

  1. <nil>
  2. <error>
  3. 0
  4. 1

请帮忙看看。非常感谢!

英文:

I want to output an error if the field in json contains a value of null. How can I do it? I have tried "encoding/json". Maybe I need another library.

Code example:

  1. package main
  2. import (
  3. &quot;encoding/json&quot;
  4. &quot;fmt&quot;
  5. &quot;strings&quot;
  6. )
  7. type Item struct {
  8. Value *int
  9. }
  10. func main() {
  11. var jsonBlob = `[
  12. {},
  13. {&quot;Value&quot;: null},
  14. {&quot;Value&quot;: 0},
  15. {&quot;Value&quot;: 1}
  16. ]`
  17. var items []Item
  18. err := json.NewDecoder(strings.NewReader(jsonBlob)).Decode(&amp;items)
  19. if err != nil {
  20. fmt.Println(&quot;error:&quot;, err)
  21. }
  22. for _, a := range items {
  23. if a.Value != nil {
  24. fmt.Println(*a.Value)
  25. } else {
  26. fmt.Println(a.Value)
  27. }
  28. }
  29. }

I got:

  1. &lt;nil&gt;
  2. &lt;nil&gt;
  3. 0
  4. 1

I want:

  1. &lt;nil&gt;
  2. &lt;error&gt;
  3. 0
  4. 1

Please help. Many thanks!

答案1

得分: 4

如果你想控制类型的反序列化过程,你可以实现json.Unmarshaler接口。

由于映射(map)允许你区分未设置的值和null值,首先将其反序列化为通用的map[string]interface{}类型,可以让你在不对JSON进行标记化的情况下检查值。

  1. type Item struct {
  2. Value *int
  3. }
  4. func (i *Item) UnmarshalJSON(b []byte) error {
  5. tmp := make(map[string]interface{})
  6. err := json.Unmarshal(b, &tmp)
  7. if err != nil {
  8. return err
  9. }
  10. val, ok := tmp["Value"]
  11. if ok && val == nil {
  12. return errors.New("Value cannot be nil")
  13. }
  14. if !ok {
  15. return nil
  16. }
  17. f, ok := val.(float64)
  18. if !ok {
  19. return fmt.Errorf("unexpected type %T for Value", val)
  20. }
  21. n := int(f)
  22. i.Value = &n
  23. return nil
  24. }

你可以在这里查看代码示例:https://play.golang.org/p/MNDsQpfEJA

英文:

If you want to control how a type is unmarshaled, you can implement json.Unmarshaler

Since a map allows you to tell the difference between an unset value, and a null value, unmarshaling first into a generic map[string]interface{} will allow you to inspect the values without tokenizing the JSON.

  1. type Item struct {
  2. Value *int
  3. }
  4. func (i *Item) UnmarshalJSON(b []byte) error {
  5. tmp := make(map[string]interface{})
  6. err := json.Unmarshal(b, &amp;tmp)
  7. if err != nil {
  8. return err
  9. }
  10. val, ok := tmp[&quot;Value&quot;]
  11. if ok &amp;&amp; val == nil {
  12. return errors.New(&quot;Value cannot be nil&quot;)
  13. }
  14. if !ok {
  15. return nil
  16. }
  17. f, ok := val.(float64)
  18. if !ok {
  19. return fmt.Errorf(&quot;unexpected type %T for Value&quot;, val)
  20. }
  21. n := int(f)
  22. i.Value = &amp;n
  23. return nil
  24. }

https://play.golang.org/p/MNDsQpfEJA

huangapple
  • 本文由 发表于 2017年8月17日 03:24:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/45721470.html
匿名

发表评论

匿名网友

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

确定