Что такое встраивание в Go
Что проверяют
Понимаете ли вы, что повторное использование в Go строится на композиции, и не пересказываете ли наследование чужими словами. Вопрос быстро показывает, знает ли кандидат правила продвижения имён и границу, за которой встраивание перестаёт вести себя как подтип.
Как отвечать
Встраивание это поле без имени: в структуру или интерфейс включается тип, и его поля и методы становятся доступны у внешнего типа напрямую.
type Logger struct{ prefix string }
func (l Logger) Log(msg string) {}
type Service struct {
Logger
name string
}Service получает метод Log, и если Logger реализовывал какой-то интерфейс, то теперь его реализует и Service. Имя поля совпадает с именем типа, поэтому обращение s.Logger.Log(...) тоже работает и становится обязательным при конфликте имён.
Разрешение идёт по глубине: имя на меньшей глубине перекрывает более глубокое, а два одинаковых имени на одной глубине не перекрывают друг друга, и обращение без уточнения просто не компилируется.
Отдельно стоит назвать применения: встраивание интерфейса в структуру, чтобы получить заглушку с одним переопределённым методом; встраивание мьютекса ради коротких s.Lock(); встраивание интерфейсов друг в друга, как это сделано у io.ReadWriter.
Где спотыкаются
Называют встраивание наследованием. Виртуальной диспетчеризации здесь нет: метод встроенного типа, вызывая другой метод, вызовет свой собственный, а не одноимённый у внешнего типа. Переопределение в привычном смысле молча не сработает.
Не думают о публичном интерфейсе. Встроенный тип выносит наружу все свои экспортируемые методы, включая те, которые наружу не планировались. Именованное поле честнее, а встраивание уместно там, где внешний тип действительно обязан вести себя как встроенный.
Забывают, что правила касаются сериализации и копирования. Поля встроенной структуры поднимаются в JSON на верхний уровень, и раскладка ответа меняется незаметно. Встраивание по значению копируется вместе со структурой, поэтому встроенный мьютекс копируется тоже, и защита ломается.