Определение вывода программы при работе с nil‑интерфейсом и nil‑указателем

Первый заказ успешно выведет ID 1. Второй возвращает интерфейс с nil-указателем внутри, поэтому проверка order2!=nil проходит, а GetID вызывает panic при разыменовании.

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

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

Первый заказ успешно выведет ID 1. Второй возвращает интерфейс с nil-указателем внутри, поэтому проверка order2!=nil проходит, а GetID вызывает panic при разыменовании.

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

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

Условие

Необходимо предсказать, какой текст будет выведен при выполнении программы, учитывая особенности сравнения интерфейсов с nil в Go.

type Order interface {
  GetID() int
}

type orderStruct struct {
  ID int
}

func (o *orderStruct) GetID() int {
  return o.ID
}

func createOrder(shouldCreate bool) Order {
  var order *orderStruct
  fmt.Println("in createOrder: ", order == nil)

  if shouldCreate {
    order = &orderStruct{ID: 1}
  }
  return order
}

func main() {
  order1 := createOrder(true)
  if order1 != nil {
    fmt.Printf("Order1 has ID: %d\n", order1.GetID())
  } else {
    fmt.Println("Order1 is nil")
  }

  order2 := createOrder(false)
  if order2 != nil {
    fmt.Printf("Order2 has ID: %d\n", order2.GetID())
  } else {
    fmt.Println("Order2 is nil")
  }
}

Ответ

Первый заказ успешно выведет ID 1. Второй возвращает интерфейс с nil-указателем внутри, поэтому проверка order2!=nil проходит, а GetID вызывает panic при разыменовании.

В обоих вызовах сначала печатается, что локальный указатель равен nil. Далее для true появляется строка Order1 has ID: 1. Для false ветка Order2 is nil не выполняется: динамический тип *orderStruct делает интерфейс ненулевым. Исправление — при shouldCreate=false возвращать явный nil интерфейса, а при true — созданный объект.

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

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

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

Подробнее