Интерфейс - это тип, определяющий сигнатуры одного или более методов. Интерфейсы являются полностью абстрактными, поэтому нет никакой возможности создавать их экземпляры. Однако имеется возможность создавать переменные с типами интерфейсов, которым затем можно присваивать значения любого конкретного типа, обладающего методами интерфейса.
Пример
Ex1
typeExchangerinterface{Exchange()}typeMyStringstruct{teststring}func(mystr *MyString)Exchange(){mystr.test=...}func(mystr *MyString)String()string{returnmystr.test}// все, тип MyString реализует интерфейс Exchanger и fmt.Stringer, и если где-то будет приниматься// тип Exchanger - можно отправлять MyString
Ex2
Доступ к методам interface{}
Доступ к методам значения переданного как значение типа interface{}, можно получить, выполнив операцию приведения типа, выбора по типу или прибегнув к помощи механизма интроспекции.
Type assertions (выбор по типу)
Общий вид
Пример
Особенности
Принято называть интерфейсы именами, оканчивающимися на "er" - Writer, Reader, Exchanger...
Интерфейсы могут встраиваться в другие интрефейсы подобно другим типам.
Интерфейсы могут встраиваться в структуры и другие пользовательские типы: это означает, что структура может хранить любой тип, реализующий этот интерфейс.
Пустой интерфейс interface{} может использоваться для ссылки на любое значение (как Object в Java).
Неправильно выстраивать иерархию в Go из интерфейсов: правильно применять композиционный подход. То же верно и для структур.
Нормально, если интерфейс описывает одну-две функции.
// Интерфейс
type InterfaceTest interface {
TestFunction() (interface{}, error)
}
// Объект, соотв интерфейсу
type objectTest struct {
fieldTest string
}
// Конструктор объекта
func ConstructorTest() InterfaceTest {
res := objectTest{
fieldTest: "test",
}
return &res
}
// Реализованный интерфейс для объекта
func (beta *objectTest) TestFunction() (interface{}, error) {
return nil, nil
}
t := i.(T)
t, ok := i.(T)
package main
import "fmt"
func main() {
var i interface{} = "hello"
s := i.(string)
fmt.Println(s)
s, ok := i.(string)
fmt.Println(s, ok)
f, ok := i.(float64)
fmt.Println(f, ok)
f = i.(float64) // panic
fmt.Println(f)
}