我想将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)
}
Example in Playground
输出:
显然,在调用json.Marshal之前,我可以删除MarshalJSON方法并在主函数中调用Lock()。但是,我的问题是:
有什么方法可以在结构的MarshalJSON方法中调用json.Marshal(或至少让json包处理编码)?
奖金问题
为什么我的程序没有冻结?当第二次递归调用MarshalJSON时,是否不应该锁定该结构?
最佳答案
您可以在递归调用中为类型加上别名。它在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/