На этом шаге рассмотрим интерфейсы в Go.
Интерфейс – это тип, определяющий сигнатуры одного или более методов. Интерфейсы являются полностью абстрактными, поэтому нет никакой возможности создавать их экземпляры. Однако имеется возможность создавать переменные с типами интерфейсов, которым затем можно присваивать значения любого конкретного типа, обладающего методами интерфейса.
Тип interface{} – это интерфейс, определяющий пустое множество методов. Этому интерфейсу удовлетворяет любое значение, независимо от того, имеет оно методы или нет, – в конце концов, если значение имеет методы, это множество методов включает пустое множество наряду со множеством фактических методов. По этой причине тип interface{} можно использовать для представления любых значений.
Относительно значения, переданного как значение типа interface{}, нельзя вызывать методы (даже если они действительно имеются), поскольку представляющий его интерфейс не имеет методов. То есть в общем случае лучше передавать значения либо с их фактическим типом, либо с интерфейсом, определяющим методы, которые предполагается использовать.
Доступ к методам значения, переданного как значение типа interface{}, можно получить, выполнив операцию приведения типа, выбора по типу или прибегнув к помощи механизма интроспекции.
Приведем пример простого интерфейса:
type Exchanger interface { Exchange() }
Интерфейс Exchanger определяет единственный метод Exchange(), не имеющий аргументов и ничего не возвращающий. Имя интерфейса здесь выбрано с учетом соглашений, принятых в языке Go, согласно которым имена интерфейсов должны заканчиваться на "er".
Для интерфейсов вполне обычное явление – определять единственный метод. Например, интерфейсы io.Reader и io.Writer из стандартной библиотеки определяют по одному методу. В действительности интерфейсы определяют API (Application Programming Interface – прикладной программный интерфейс), то есть нуль или более методов, но никак не регламентируют, что должны делать эти методы.
На следующем шаге рассмотрим использование интерфейсов в Go.