Опишите систему типов в языке Go

Ответ

Go имеет статическую, строгую, номинативную систему типов с выводом типов.

Разберём по частям:

  1. Статическая (Static Typing) Типы всех переменных известны и проверяются на этапе компиляции. Это позволяет отловить множество ошибок до запуска программы.

    var a int = 10
    // a = "hello" // Ошибка компиляции: cannot use "hello" (type string) as type int
  2. Строгая (Strong Typing) Go не допускает неявных преобразований между разными типами. Любое преобразование должно быть явным.

    var i int = 42
    var f float64
    // f = i         // Ошибка компиляции
    f = float64(i) // Правильно: явное приведение типа
  3. Вывод типов (Type Inference) Компилятор может автоматически определять тип переменной на основе её значения при инициализации с помощью оператора :=.

    // Вместо var s string = "Go"
    s := "Go" // Компилятор сам выводит тип string

    Важно понимать, что это не динамическая типизация. Тип переменной s определяется один раз и не может быть изменён.

  4. Номинативная для типов, структурная для интерфейсов

    • Номинативная (Nominative): Два типа считаются одинаковыми, только если у них одно и то же имя и они объявлены в одном пакете. type MyInt int создаёт новый, отдельный тип.
    • Структурная (Structural): Для интерфейсов Go использует структурную типизацию, также известную как "утиная типизация" (duck typing). Любой тип, который реализует все методы интерфейса, неявно удовлетворяет этому интерфейсу. Ему не нужно явно указывать implements.
    type Speaker interface {
        Speak() string
    }
    
    type Dog struct{}
    func (d Dog) Speak() string { return "Woof!" } // Dog неявно реализует Speaker
    
    type Human struct{}
    func (h Human) Speak() string { return "Hello!" } // Human тоже реализует Speaker