首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Golang -客户解封器/封送器在指针上为nil/null值

Golang -客户解封器/封送器在指针上为nil/null值
EN

Stack Overflow用户
提问于 2022-09-29 19:59:13
回答 1查看 97关注 0票数 2

Golang -客户解封器/封送器在指针上为nil/null值

我试图在指针类型上实现自定义的UnmarshalJSONMarshalJSON,但是如果来自json的数据是null/nil,则不会调用这些函数,如下例所示:

代码语言:javascript
复制
package main

import (
    "encoding/json"
    "fmt"
)

type A struct {
    B *B `json:"b,omitempty"`
}

type B int

// Only for displaying value instead of
// pointer address when calling `fmt.Println`
func (b *B) String() string {
    if b == nil {
        return "nil"
    }

    return fmt.Sprintf("%d", *b)
}

// This function is not triggered when json
// data contains null instead of number value
func (b *B) UnmarshalJSON(data []byte) error {
    fmt.Println("UnmarshalJSON on B called")

    var value int
    if err := json.Unmarshal(data, &value); err != nil {
        return err
    }

    if value == 7 {
        *b = B(3)
    }

    return nil
}

// This function is not triggered when `B`
// is pointer type and has `nil` value
func (b *B) MarshalJSON() ([]byte, error) {
    fmt.Println("MarshalJSON on B called")

    if b == nil {
        return json.Marshal(0)
    }

    if *b == 3 {
        return json.Marshal(7)
    }

    return json.Marshal(*b)
}

func main() {
    var a A

    // this won't call `UnmarshalJSON`
    json.Unmarshal([]byte(`{ "b": null }`), &a)
    fmt.Printf("a: %+v\n", a)

    // this won't call `MarshalJSON`
    b, _ := json.Marshal(a)
    fmt.Printf("b: %s\n\n", string(b))

    // this would call `UnmarshalJSON`
    json.Unmarshal([]byte(`{ "b": 7 }`), &a)
    fmt.Printf("a: %+v\n", a)

    // this would call `MarshalJSON`
    b, _ = json.Marshal(a)
    fmt.Printf("b: %s\n\n", string(b))
}

产出:

代码语言:javascript
复制
a: {B:nil}
b: {}

UnmarshalJSON on B called
a: {B:3}
MarshalJSON on B called
b: {"b":7}

我的问题是:

  • 为什么不使用指针类型上的UnmarshalJSON/MarshalJSON值调用null/nil
  • 每次数据为null/nil且类型为指针时如何调用A,而不是在A类型上实现UnmarshalJSON/MarshalJSON,并从A级别修改b属性
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-30 09:29:18

,简称

目前,解除封送/封送Go结构只会发出非零字段,因为nil pointer是一个Go值为零,所以在本例中不调用UnmarshalJSON/MarshalJSON

此外,似乎有一些相关的建议。

然而,现在还没有解决办法。

每个代码的 解组员

解编组器将UnmarshalJSON([]字节(“null”))实现为无操作。

代码语言:javascript
复制
// By convention, to approximate the behavior of Unmarshal itself,
// Unmarshalers implement UnmarshalJSON([]byte("null")) as a no-op.
type Unmarshaler interface {
    UnmarshalJSON([]byte) error
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73901013

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档