[БЕЗ_ЗВУКА] В этом видео мы поговорим про пустые интерфейсы. Пустой интерфейс — это интерфейс, который может принять в себя вообще любую переменную, потому что у него нет никаких требований к реализации. Начнём рассматривать пустые интерфейсы с демонстрации их работы. У нас есть вывод, у нас есть наш кошелёк, и есть вывод нашего кошелька в двух форматах. Первый формат — это полное Go-шное представление структуры, второй формат — это строка. Запустим. Итак, первый вывод вывел нам прямо имя структуры вместе со всеми полями и значениями, которые там есть. Второй вывод вывел нам какой-то текст: кошелёк, в котором 100 денег. Теперь я вам расскажу, каким образом это получилось, каким образом функция Printf() догадалась, что там надо видеть. Явно, что функция стандартной библиотеки не знает ничего про тип, который я только что определил. На самом деле функция Printf() принимает в себя пустой интерфейс. Поэтому мы туда можем передавать абсолютно любые параметры, одни за другими, она все из них выведет. Но каким образом получилось, что вывелось то, что надо? Дело в том, что если нашу структуру, наш тип данных даже реализует интерфейс Stringer, который выглядит вот так, [ЗВУК] это внутренний тип, то тогда функция Pintf() вызовет функцию String, она, эта структура, например, которая уже отформатирует вывод так, как мы хотим. То есть у моего кошелька есть метод String(), который возвращает строку и который как раз форматирует кошелёк, в котором сколько-то денег. Пустые интерфейсы — очень полезная вещь, когда нам нужно делать совсем генерические функции, которые работают со всем, чем угодно. Как внутри происходит преобразование интерфейсов, я покажу. Вот функция уже знакомая нам, функция для оплаты, которую я немножко переделал. Теперь она принимает не интерфейс-платильщик, а пустой интерфейс. То есть я могу передать туда вообще всё, что угодно, и функция должна проверить не на этапе компиляции соответствие интерфейса, а уже в runtime'е. Действительно ли я получу там то, что надо? Итак, то есть я определил пустой интерфейс, моего плательщика, объявляю флаг, что всё хорошо. Теперь я пытаюсь этот интерфейс преобразовать к плательщику. То есть я хочу проверить, является ли то, что мне пришло, интерфейсом? Если не является, говорю, что нельзя. Ну а поскольку оно, если является, я уже присвоил переменную p плательщика, то я произвожу оплату. Как это работает? Отлично. Мой кошелёк прошёл успешно, а вот slice int'ов либо float — они не прошли, потому что они не реализуют интерфейс «плательщик». Это очень мощный инструмент, и мы будем неоднократно сталкиваться с применением пустого интерфейса.