我想在将结构编码为 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)
}
输出:
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/