Шаг 81.
Язык программирования Go.
Пользовательские типы

    На этом шаге рассмотрим определение пользователльских типов в Go.

    Пользовательские типы определяются с помощью ключевого слова type:

type имяТипа определениеТипа 

    Имя типа может быть любым допустимым идентификатором, уникальным в пределах пакета или функции. В качестве определения типа могут использоваться имя любого встроенного типа (например, string, int, срез, отображение или канал), интерфейса, определение структуры или сигнатура функции.

    В некоторых ситуациях бывает достаточно просто определить пользовательский тип, в других бывает необходимо добавить методы, чтобы сделать его по-настоящему полезным. Приведем примеры пользовательских типов без методов.

type Count int
type StringMap map[string]string
type FloatChan chan float64

    Ни один из этих типов не выглядит особенно полезным, хотя их использование может улучшить удобочитаемость программы и в будущем изменить тип, лежащий в его основе. То есть они играют роль простейшего механизма абстракции.

var i Count = 7
i++
fmt.Println(i)
sm := make(StringMap)
sm["key1"] = "Значение1"
sm["key2"] = "Значение2"
fmt.Println(sm)
fc := make(FloatChan, 1)
fc <- 2.29558714939
fmt.Println(<-fc)

    Типы, подобные типам Count, StringMap и FloatChan, основанные непосредственно на встроенных типах, можно использовать точно так же, как сами встроенные типы. Например, к значению пользовательского типа StringSlice []string можно применить встроенную функцию append(), но его необходимо будет преобразовать в значение встроенного типа, прежде чем передать функции, ожидающей получить значение этого встроенного типа. А иногда бывает необходимо выполнить обратное действие и преобразовать значение встроенного типа в значение пользовательского типа, чтобы получить возможность использовать дополнительные методы пользовательского типа.

    При работе с функциями высшего порядка часто бывает удобно объявить тип, определяющий сигнатуру передаваемой функции.

type RuneForRuneFunc func(rune) rune 

    Здесь определяется сигнатура функции, принимающей и возвращающей единственное значение типа rune.

var removePunctuation RuneForRuneFunc

    Переменная removePunctuation предназначена для хранения ссылки на функцию типа RuneForRuneFunc (то есть с сигнатурой func(rune) rune). Подобно всем переменным в языке Go, она автоматически инициализируется нулевым значением , то есть в данном случае значением nil.

phrases := []string{"Казнить, нельзя, помиловать.", "Быть или не быть."}
removePunctuation = func(char rune) rune {
    if unicode.Is(unicode.Terminal_Punctuation, char) {
        return -1
    }
    return char
}
processPhrases(phrases, removePunctuation)

    Здесь создается анонимная функция с сигнатурой, соответствующей RuneForRuneFunc, и передается пользовательской функции processPhrases().

func processPhrases(phrases []string, function RuneForRuneFunc) {
    for _, phrase := range phrases {
        fmt.Println(strings.Map(function, phrase))
    }
} 

    Архив с примерами можно взять здесь.

    На следующем шаге рассмотрим добавление дополнительных методов в Go.


Предыдущий шаг Содержание Следующий шаг