Я хотел добавить RLock/RUnlock в структуру, когда он был настроен на json.
В приведенном ниже примере показано, что я пытаюсь сделать. Однако это не работает, потому что вызывается каждый json.Marshal
, он будет запускать метод Object.MarshalJSON
, который сам по себе вызывает json.Marshal, вызывая бесконечный цикл.Блокировка объекта во время json.Marshal в Go
Пример:
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)
}
Выход:
Ранжирование Объект
сортировочных Объект
сортировочных Объект
...
Очевидно, что я могу удалить метод MarshalJSON и вызвать функцию Lock() внутри основной функции перед вызовом json.Marshal. Но, мой вопрос скорее:
Есть ли способ вызвать json.Marshal (или, по крайней мере, пакет json обрабатывать кодировку) в методе MarshalJSON структуры?
Бонус вопрос
Почему моя программа не замерзает? Не следует ли блокировать структуру, когда маршал JSON называется рекурсивно второй раз?
почему вы хотите, чтобы заблокировать объект? – akira
@Akira: Если у меня есть несколько goroutines, совместно использующих объект, я хочу, чтобы другие подпрограммы не меняли данные во время их кодирования. В моем примере у меня этого нет, но этот пример не предназначен для отображения фактического использования. – ANisus
в зависимости от размера объекта для кодирования: копирование структуры является допустимым вариантом, imho. – akira