0.97M
Category: programmingprogramming

Golang

1.

Golang
27.02.23

2.

Определение структур
• Кратко о главном. Что необходимо знать:
1. Что такое структуры – это типы данных, состоящие из полей.
2. Почему они полезные для конечного пользователя? – позволяют
нам определять пользовательские типы данных.
3. Как они используются? – ключевые слова type и struct
используются для определения типа, позволяя указывать имена
полей и типы этих полей.

3.

Ограничение или предосторожности?
• Стоит следить за тем, чтобы избежать непреднамеренного
дублирования значений структуры и убедиться, что поля, в
которых хранятся указатели, инициализированы до их
использования.
• -----------------------------------------------------------------------------------• Альтернативы?
• Какие-нибудь простейшие приложения могут использовать только
встроенные типы данных, но большинству приложений
потребуется определить пользовательские типы, для которых
структуры являются единственным вариантом.

4.

• Где классы?
• -----------------------------------------------------------------------------------• Go не делает различий между структурами и классами, как это
делают другие языки. Все пользовательские типы данных
определяются как структуры, и решение о передачи их по ссылке
или по значению принимается в зависимости от того,
используется ли указатель.

5.

• Так или иначе, если вы уже знакомы с каким-либо объектноориентированным языком, то вас, возможно, заинтересует (это же
Go), чем структуры отличаются от классов.
• На это можно дать очень простой ответ: в языке Go, опять таки,
нет классов, потому что в нём нет наследования.
• В то же время некоторые возможности объектноориентированных языков есть и в Go, только реализуются
немного по-другому.
• Но об этом попозже.

6.

• Определение и использование структуры
• -----------------------------------------------------------------------------------• Пользовательские типы данных определяются с помощью
функции структур Go, которая продемонстрирована на скрине
ниже:

7.

• На этом же скрине в качестве демонстрации показано, что можно
спокойно менять значения структур (полей).
• -----------------------------------------------------------------------------------• Пользовательские типы данных известны в Go, как структурные
типы и определяются с помощью ключевого слова type, имени и
ключевого слова struct.
• Скобки же, в свою очередь, окружают ряд полей, каждое из
которых определяется именем и типом. Поля одного типа могут
быть объявлены вместе.
• При этом все поля должны иметь разные имена.
• Тип структуры Product из примера имеет три поля: name, category
и price.

8.

• Подобно тому как в объявлении var сначала указывается имя
переменной, а затем – её тип, здесь тоже сначала указывается имя
поля структуры, а затем – её тип.
• Структурный тип можно определить внутри или за пределами
функции. Если структурный тип задан внутри функции, то его
можно использовать только в её пределах.
• -----------------------------------------------------------------------------------• Строго говоря, область видимости определения структуры может
быть ограничена до любого уровня блоков.

9.

• Создание структурных значений
• -----------------------------------------------------------------------------------• Следующим шагом после определения структуры, является
создание значения с использованием пользовательского типа, что
делается с использованием имени типа структуры, за которым
следуют фигурные скобки, содержащие значения для полей
структуры.

10.

• Go не позволяет использовать структуры с ключевым словом
const, и компилятор сообщит об ошибке, если вы попытаетесь
определить константную структуру.
• -----------------------------------------------------------------------------------• Использование значения структуры
• Доступ к полям значения структуры осуществляется через имя,
присвоенное переменной, так что доступ к значению поля name
значения структуры, присвоенного переменной kolbasa,
осуществляется с помощью kolbasa.name:

11.

• Частичное присвоение значений структуры
• -----------------------------------------------------------------------------------• При создании значения структуры не обязательно указывать
значения для всех полей:

12.

• После объявления структурного типа мы можем определить
переменные этого типа:

13.

• В данном случае используется объявление var. Поскольку
значение не присваивается переменной fred, она получает нулевое
значение для структурного типа Person. У структуры, равной
нулевому значению, каждое поле содержит нулевое значение того
типа, к которому относится это поле.
• -----------------------------------------------------------------------------------• Вы также можете присвоить переменной литерал структуры:

14.

• В структурах нет никакой разницы между присвоением
переменной пустого литерала структуры и объявлением
переменной без присвоения значения.
• И в том, и в другом случае все поля структуры будут
инициализированы нулевыми значениями соответствующего
типа.
• В случае непустого литерала структуры можно использовать два
стиля записи. Первый стиль сводится к тому, чтобы перечислить
внутри фигурных скобок значения полей, разделив их запятыми:

15.

• При использовании такого формата литерала структуры
необходимо указывать значения всех полей структуры в том же
порядке, в каком они объявляются в определении структуры.
• -----------------------------------------------------------------------------------• Второй стиль записи литерала структуры выглядит так же, как и
стиль записи литерала карты (map – изучим позже, но можете и
лично посмотреть, кому особо интересно):

16.

• Имена полей в структуре используются для указания их значений.
Применяя этот стиль, можно не указывать значения некоторых
полей и перечислять поля в любом порядке.
• Всем неуказанным полям будет присвоено нулевое значение
соответствующего типа. Эти два стиля записи литерала структуры
нельзя сочетать друг с другом: либо все поля должны указываться
с ключами, либо ни одно из них.
• -----------------------------------------------------------------------------------• В случае небольших структур, у которых всегда указываются
имена всех полей, будет вполне уместным более простой стиль
записи.
• Во всех остальных случаях лучше использовать имена ключей.

17.

• Хотя этот стиль (с именами ключей) более многословен, он
позволяет четко указать, какое значение присваивается какому
полю, без необходимости сверяться с определением структуры.
• Кроме того, литерал структуры в таком формате проще
поддерживать. Если вы будете инициализировать структуру, не
используя имена полей, то добавление в структуру
дополнительных полей в одной из новых версий программы
приведёт к ошибке при компиляции.
• -----------------------------------------------------------------------------------• Для доступа к полям структуры используется точечная нотация.
• Пример уже был, но в качестве напоминания самой функции,
которая используется для вывода информации поля: функция
точки/точечной нотации.

18.

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

19.

• Определение встроенных полей
• -----------------------------------------------------------------------------------• Если поле определено без имени, оно известно, как встроенное
поле, и доступ к нему осуществляется с использованием имени
его типа:

20.

• Тип структуры stockLevel имеет два поля.
• Первое поле встроено и определяется только с использованием
типа, который является типом структуры Product, как показано в
схеме:

21.

• Доступ к встроенным полям осуществляется с использованием
имени типа поля, поэтому эта функция наиболее полезна для
полей, тип которых является структурой.
• В данном случае встроенное поле определяется типом Product,
что означает, что оно назначается и читается с использованием
Product в качестве имени поля.

22.

• Как уже было сказано, имена полей должны быть уникальными
для типа структуры, что означает, что вы можете определить
только одно встроенное поле для определённого типа.
• Если вам нужно определить два поля одного типа, вам нужно
будет присвоить имя одному из них, как показано в следующем
листинге:

23.

• Тип stockLevel имеет два поля типа Product, но только одно из них
может быть встроенным полем.
• Для второго поля я присвоил имя, через которое осуществляется
доступ к полю.

24.

• Анонимные структуры
• -----------------------------------------------------------------------------------• Вы также можете объявить, что переменная реализует
структурный тип, без предварительного присвоения имени этому
структурному типу.
• Такие структуры называют анонимными:

25.

• В данном примере переменные Person и pet относятся к
анонимному структурному типу.

26.

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

27.

• Здесь закономерно для многих может возникнуть вопрос: нафиг
может понадобиться тип данных, связанный только с одним
экземпляром?
• Анонимные структуры удобно использовать в двух
распространённых случаях.
• Первым случаем является преобразование внешних данных в
структуру или, наоборот, структуры во внешние данные
(например, данные в формате JSON или буферы протоколов).
• Эти виды преобразований называют демаршаллингом и
маршаллингом данных.

28.

• Второй областью применения анонимных структур является
написание тестов. Чуть позже будет пример среза анонимных
структур при написании табличных тестов.

29.

• Сравнение значений структуры
• -----------------------------------------------------------------------------------• Значения структур сопоставимы, если можно сравнить все их
поля.
• В следующем листинге создаётся несколько значений структуры и
применяется оператор сравнения, чтобы определить, равны ли
они:

30.

• Значения структуры p1 и p2 не равны, в то время как та же
структура p1 является равной структуре p3.
• Но структуры нельзя сравнивать, если тип структуры определяет
поля с несравнимыми типами, например срезы, как показано на
следующем скрине:

31.

• Оператор сравнения Go нельзя применять к срезам, что как бы
говорит про невозможность сравнения значений Product.
• -----------------------------------------------------------------------------------• На этом покамест всё. Удачки всем :3
English     Русский Rules