Вот проблема, с которой я сталкиваюсь, используя golang struct
type User struct {
name string `json:"name"`
email string `json:"email"`
}
Теперь я хочу, чтобы доступ и изменение этих полей структуры были безопасными одновременно, и, следовательно, я добавил мьютекс и добавил методы, которые блокируютmutex Пользовательский код теперь может получать доступ и мутировать только через методы и не может напрямую обращаться к полям
type User struct {
name string `json:"name"`
email string `json:"email"`
sync.RWMutex `json:"-"`
}
func (u *User) Name() string {
u.RLock()
defer u.RUnlock()
return u.name
}
func (u *User) Email() string {
u.RLock()
defer u.RUnlock()
return u.email
}
func (u *User) SetName(p string) {
u.Lock()
defer u.Unlock()
u.name = p
}
func (u *User) SetEmail(p string) {
u.RLock()
defer u.RUnlock()
u.email = p
}
Пока все хорошо, но проблема в том, что json / bson marshalling терпит неудачу, так как требует экспортируемых полей
Таким образом, я реализую пользовательский маршаллинг, который возвращает похожую структуру, но с экспортированными полями
func (self User) MarshalJSON() ([]byte, error) {
var usr struct {
Name string `json:"name"`
Email string `json:"email,omitempty"`
sync.RWMutex `json:"-"`
}
return json.Marshal(usr)
}
func (self *User) UnmarshalJSON(b []byte) error {
var usr struct {
Name string `json:"name"`
Email string `json:"email"`
sync.RWMutex `json:"-"`
}
if err := json.Unmarshal(b, &usr); err != nil {
return err
}
self.name = usr.Name
self.email = usr.Email
return nil
}
Но это не полностью делает безопасность параллелизма структуры пользователя, так как код маршалинга не заблокирован.
MyВопрос в том, как заставить код маршаллинга использовать тот же мьютекс?Создание глобального мьютекса не решит проблему, так как мы создаем несколько экземпляров структуры.Пользовательская структура, объявленная в маршалинге, отличается от основной пользовательской структуры, поэтому блокировка мьютекса внутренней структуры не имеет смысла.
Какой лучший способ добиться этого?