Как утверждает @phipsgabler, вы смешиваете код из разных версий Julia.
В этом разделе c topi c вы также можете посмотреть мой "Краткий учебник Julia", в разделе topi c из " пользовательских структур ".
Та же самая топи c, расширенная, доступна в книге " Julia Quick Syntax Reference " (Apress, 2019 ) из которого я сообщаю об исключении из неотредактированного источника (все еще полно ошибок Engli sh, но вы должны получить точку ..):
Пользовательские типы
В главе 2 «Данные Типы и структуры "мы обсудили встроенные типы, включая контейнеры. В этой главе мы расскажем, как создавать пользовательские типы.
"тип" против "структуры":
Давайте разберемся с этими двумя терминами и их значением в языке Julia. контекст.
Под типом объекта мы подразумеваем, как на простом английском sh, набор характеристик, которыми объект может быть описан. Например, объект типа sheet может быть описан с его размерами, весом, цветом.
Все значения в Julia являются истинными объектами, принадлежащими данному типу (они являются отдельными "экземплярами" данного типа).
Типы Julia включают в себя так называемые типы примитивов , состоящие из фиксированного количества битов (как и все числовые типы .. Int64
, Float64
, но также Char
..) и составные типы или структуры , где набор характеристик объекта описан через несколько полей и переменное число битов.
Обе структуры и тип примитива могут быть определены пользователем и иерархически организованы. Структуры примерно соответствуют тому, что классы известны в других языках.
Определение примитивного типа
Определяемый пользователем тип примитива определяется с ключевым словом primitive type
и только его имя и количество битов, которые ему требуются:
primitive type [name] [bits] end
Например:
primitive type My10KBBuffer 81920 end
ВАЖНО: ограничение A (тока) Юлия говорит, что число битов должно быть кратным 8 ниже 8388608.
При желании можно указать родительский тип:
primitive type [name] <: [supertype] [bits] end
Обратите внимание, что внутреннее представление двух пользовательских типов с одинаковым количеством битов абсолютно одинаково. Единственное, что могло бы измениться, - это их имена, но это важное различие: это способ, которым функции определяются, чтобы действовать, когда данные объекты этих типов передаются как аргументы, которые изменяются, т. Е. Использование в программе именованных типов различает guish их, а не их реализация.
Определение структуры
Подобным образом примитивных типов, для определения структуры мы используем ключевое слово mutable struct
, придаем структуре name, укажите поля и закройте определение с помощью ключевого слова end
:
mutable struct MyOwnType
field1
field2::String
field3::Int64
end
Обратите внимание, что, хотя вы можете по желанию определить каждое отдельное поле определенного типа (например, field3 :: Int64), вы не может определить поля как подтипы данного типа (например, field3<:Number
). Однако для этого можно использовать шаблоны в определении структуры:
mutable struct MyOwnType{T<:Number}
field1
field2::String
field3::T
end
Используя шаблоны, определение структуры динамически создается при первом создании объекта, поле field3 которого имеет тип T
. .
Тип, с которым вы аннотируете отдельные поля, может быть либо примитивным (как в примере выше), либо ссылкой на другую структуру (см. Пример ниже). +
Также обратите внимание, что в отличие от других языков высокого уровня (например, Python), вы не можете добавлять или удалять поля из структуры после того, как вы впервые ее определили. Если вам нужна эта функциональность, используйте вместо нее <>, но имейте в виду, что вы будете менять эту гибкость на худшую производительность.
С другой стороны, чтобы получить производительность (но снова торговать с гибкостью), вы можете опустить ключевое слово mutable
перед struct
. Это будет ограничивать то, что после создания объекта этого типа его поля больше не могут быть изменены (т. Е. Структуры являются неизменяемыми по умолчанию).
Обратите внимание, что изменяемые объекты - как массивы - остаются изменяемыми и в неизменяемой структуре.