我想将一个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时,不应该锁定结构吗?
您可以在递归调用上为该类型添加别名.这是播放.
别名类型(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)