Результат — 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 будет работать ожидаемо.