Сравнение значений интерфейсных переменных

Результат — false: CreateRepoA возвращает интерфейс с типом *MemRepo и nil-указателем, а CreateRepoB — полностью nil-интерфейс.

Короткий ответ

Что ответить на собеседовании

Результат — false: CreateRepoA возвращает интерфейс с типом *MemRepo и nil-указателем, а CreateRepoB — полностью nil-интерфейс.

Подробный разбор

Ответ с пояснениями

Условие

Определите, какой результат будет выведен при выполнении следующей программы.

type MemRepo struct {
  Data string
}

type Repository interface{}

func CreateRepoA() Repository {
  var ptr *MemRepo
  return ptr
}

func CreateRepoB() Repository {
  return nil
}

func main() {
  fmt.Println(CreateRepoA() == CreateRepoB())
}

Ответ

Результат — false: CreateRepoA возвращает интерфейс с типом *MemRepo и nil-указателем, а CreateRepoB — полностью nil-интерфейс.

Repository здесь является пустым интерфейсом, поэтому допускает значение любого типа, включая *MemRepo. При возврате ptr его динамический тип сохраняется даже при nil-значении.

Два результата различаются наличием типа. Сравнение в этом случае допустимо и не вызывает panic: указатели сравнимы. Для отсутствующего репозитория фабрике следует явно возвращать nil, а не упаковывать nil-указатель в интерфейс. Тогда обычная проверка результата на nil будет работать ожидаемо.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее