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

ANi*_*sus 4 json go

我想将一个RLock/RUnlock添加到结构中,当它被编组到json中时.
下面的例子显示了我尝试做的事情.但是,它不起作用,因为每个都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)
}
Run Code Online (Sandbox Code Playgroud)

游乐场中的示例

输出:

编组对象
编组对象
编组对象
...

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

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

奖金问题
为什么我的程序没有冻结?第二次递归调用MarshalJSON时,不应该锁定结构吗?

Dav*_*rth 8

您可以在递归调用上为该类型添加别名.这是播放.

别名类型(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)
}
Run Code Online (Sandbox Code Playgroud)