Разница между типом и структурой - PullRequest
7 голосов
/ 07 марта 2020

Я пытаюсь выучить Джулию и читаю книгу, в которой показаны следующие два примера кода в главе о составных типах:

1.

type Points
    x::Int64
    y::Int64
    z::Int64
end

2.

struct Point
    x::Int
    y::Int
    z::Int
end

Книга, однако, не объясняет, когда использовать struct и когда использовать type.

В чем разница?

Ответы [ 2 ]

6 голосов
/ 07 марта 2020

Это довольно запутанно в ваших источниках, так как он смешивает разные значения из несовместимых эпох в истории языка.

  • Первоначально (до 0.7, я думаете?), составные типы были объявлены либо с type, либо с immutable, где type использовалось для изменяемых типов (также было bitstype для того, что теперь называется "примитивными типами").
  • Теперь , у нас есть mutable struct и struct для целей sampe (и, соответственно, primitive type и abstract type).

Итак, в основном имена изменились, так что все способы определения типов стали более согласованными, а неизменяемые структуры стали «немаркированными».

«Изменяемый» в этом контексте означает, что вы не можете переназначить поле (p.x = 3). Это не означает, что содержимое поля не может быть изменено, если оно оказывается изменчивым (something.v[1] = 2 также будет работать, если something является неизменяемым типом!).

1 голос
/ 09 марта 2020

Как утверждает @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. Это будет ограничивать то, что после создания объекта этого типа его поля больше не могут быть изменены (т. Е. Структуры являются неизменяемыми по умолчанию).

Обратите внимание, что изменяемые объекты - как массивы - остаются изменяемыми и в неизменяемой структуре.

...