Задать вопрос
@SilentGr0ve
Первокурсник

Как в Go происходит неявное удовлетворение интерфейсу?

Меня заинтересовала следующая особенность в Go; Код для примера ниже:
package main

import "fmt"

type User struct {
	Name string
	Age  int
}

func (u User) String() string {
	return fmt.Sprintf("%s (%d years old)", u.Name, u.Age)
}

func main() {
	user := User{Name: "Alice", Age: 28}
	fmt.Println(user)
}


Вывод:
Alice (28 years old), а не {Alice 28}

Каким образом в рантайме Go происходит понимание того, что нужно использовать именно пользовательский String(), а не его базовые реализации? И можно ли даже при созданном вручную String() использовать метод String() из стандартной библиотеки?

Как это вообще может помочь в целом в работе и какие есть юзкейсы для этого? Спасибо.
  • Вопрос задан
  • 154 просмотра
Подписаться 1 Простой 2 комментария
Помогут разобраться в теме Все курсы
  • Нетология
    Go-разработчик с нуля + нейросети
    9 месяцев
    Далее
  • Хекслет
    GO-разработчик
    6 месяцев
    Далее
  • Яндекс Практикум
    Go-разработчик с нуля
    8 месяцев
    Далее
Решения вопроса 1
Интерфейс в Го, это структура с двумя полями.
1. Указатель на данные (в вашем случае на структуру User с age и name)
2. Указатель на таблицу виртуальных методов.
В таблице виртуальных методов как раз перечислены методы, которые реализованы на структуре и на рантайме через нее Го понимает, что можно вызывать, а что нельзя.

В статье https://habr.com/ru/articles/856272/ можете почитать подробнее, там описано как работает itab (таблица виртуальных методов).


Можно ли даже при созданном вручную String() использовать метод String() из стандартной библиотеки?


String в стандартной библиотеке это не метод на структуре. Это код, который через рефлексию смотрит что ему пришло и вызывает соответствующий форматтер. Одно из условий, которые он проверяет, это как раз, имплементит ли объект интерфейс Stringer, поэтому в вашем коде вызывается этот метод.
Использовать стандартный форматтер структуры получится разве что костылями, дергая вручную более "тупые" методы стандартной библиотеки или через пакет reflect вытащить данные из структуры.

Как это вообще может помочь в целом в работе и какие есть юзкейсы для этого?


Слишком общий вопрос, обычно интерфейсы используются как вариант полиморфизма и как способ уменьшения связанности кода (это чтобы не импортить какой-то пакет из своего пакета, а вместо этого принять абстрактный объект, который умеет определенные методы). Еще так избавляются от циклических зависимостей.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@Dhwtj
Что-то про Фрейду
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы