Выбор ответа Middle sync и атомики спрашивают часто обновлено

Копирование структуры с мьютексом

Вопрос

В чём ошибка кода?

type SafeCounter struct {
    mu sync.Mutex
    m  map[string]int
}

func (c SafeCounter) Inc(k string) {
    c.mu.Lock()
    defer c.mu.Unlock()
    c.m[k]++
}

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Ресивер по значению копирует мьютекс, защиты нет. У Inc ресивер SafeCounter по значению, поэтому c.mu и c.m здесь копия структуры.

Варианты ответа

  1. Для мапы нужен RWMutex, обычный Mutex её не защитит
  2. Ресивер по значению копирует мьютекс, защиты нетправильный ответ
  3. defer нельзя использовать с Unlock, нужен явный вызов
  4. Мьютекс нужно инициализировать через sync.NewMutex()

Разбор

У Inc ресивер SafeCounter по значению, поэтому c.mu и c.m здесь копия структуры. Мапа внутри общая (мапа это указатель), а мьютекс у каждого вызова свой, поэтому параллельные вызовы пишут в мапу без защиты. go vet (copylocks) сообщает об этом. Исправление: func (c *SafeCounter) Inc. RWMutex тут не поможет, defer с Unlock обычная практика, конструктора у Mutex нет, нулевое значение готово.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.