json - 在 Go 中的 json.Marshal 期间锁定对象

标签 json go

我想在将结构编码为 json 时向其添加 RLock/RUnlock。
下面的示例显示了我尝试做的事情。但是,它不起作用,因为每次调用 json.Marshal,它都会运行 Object.MarshalJSON 方法,该方法本身调用 json.Marshal,导致无限循环.

例子:

package main

import (
    "fmt"
    "encoding/json"
    "sync"
)

type Object struct {
    Name string
    Value int

    sync.RWMutex
}

func (o *Object) MarshalJSON() ([]byte, error) {
    o.RLock()
    defer o.RUnlock()

    fmt.Println("Marshalling object")

    return json.Marshal(o)
}

func main() {
    o := &Object{Name: "ANisus", Value: 42}

    j, err := json.Marshal(o)
    if err != nil {
        panic(err)
    }
    fmt.Printf("%s\n", j)
}

Example in Playground

输出:

Marshalling Object
Marshalling Object
Marshalling Object
...

显然,在调用 json.Marshal 之前,我可以删除 MarshalJSON 方法并在主函数中调用 Lock()。但是,我的问题是:

有没有什么方法可以在结构的 MarshalJSON 方法中调用 json.Marshal(或者至少让 json 包处理编码)?

奖励问题
为什么我的程序没有卡住?第二次递归调用MarshalJSON时不应该锁定struct吗?

最佳答案

您可以在递归调用中为类型添加别名。它在 Play 上.

别名类型 (JObject) 没有定义 marshal 函数,所以它不会无限递归

package main

import (
    "fmt"
    "encoding/json"
    "sync"
)

type Object struct {
    Name string
    Value int

    sync.RWMutex
}

//Type alias for the recursive call
type JObject Object

func (o *Object) MarshalJSON() ([]byte, error) {
    o.RLock()
    defer o.RUnlock()

    fmt.Println("Marshalling object")
    // This works because JObject doesn't have a MarshalJSON function associated with it
    return json.Marshal(JObject(*o)) 
}

func main() {
    o := &Object{Name: "ANisus", Value: 42}

    j, err := json.Marshal(o)
    if err != nil {
        panic(err)
    }
    fmt.Printf("%s\n", j)
}

关于json - 在 Go 中的 json.Marshal 期间锁定对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18287242/

相关文章:

javascript - 我如何告诉 Angular 2 停止自动设置 Content-Type header ?

javascript - jQuery parseJSON 不保持 json 键的顺序

http - Go中如何选择URL编码标准?

戈朗。帮助优化一段代码

c# - 可以查找 Json.net 中不存在的 Key

javascript - 如何更改 NW.js 中的 JSON 保存位置/目录

json - 使用 net/http 在 PUT "Body length 0"上出现错误

go - 在 Go 中为变量分配类型

go - 无法使用 Go 从 RabbitMQ 发送消息

c# - Asp.Net 在 json 中返回自定义对象