Типы данных¶
Система типов языка Julia является динамической, но в то же время она содержит некоторые преимущества систем статических типов, позволяя указывать, что определенные значения относятся к определенным типам.
Разделения на объектные и необъектные значения нет: все значения в Julia являются истинными объектами, имеющими тип, принадлежащий одному полностью связному графу типов, все узлы которого одинаково первоклассны как типы.
Ниже приведена сводная таблица сравнения типов данных Engee и MATLAB.
Тип (Engee/MATLAB) | Количество бит | Наименьшее значение | Наибольшее значение |
Int8 / int8 | 8 | $$-2^7$$ | $$2^7 - 1$$ |
UInt8 / uint8 | 8 | $$0$$ | $$2^8 - 1$$ |
Int16 / int16 | 16 | $$-2^{15}$$ | $$2^{1} - 1$$ |
UInt16 / uint16 | 16 | $$0$$ | $$2^{16} - 1$$ |
Int32 / int32 | 32 | $$-2^{31}$$ | $$2^{31} - 1$$ |
UInt32 / uint32 | 32 | $$0$$ | $$2^{32} - 1$$ |
Int64 / int64 | 64 | $$-2^{63}$$ | $$2^{63} - 1$$ |
UInt64 / uint64 | 64 | $$0$$ | $$2^{64} - 1$$ |
Int128 / нет | 128 | $$-2^{127}$$ | $$2^{127}- 1$$ |
UInt128 / нет | 128 | $$0$$ | $$2^{128} - 1$$ |
Bool / logical | 8/1 | false(0) | true(1) |
Bool / logical | 8/1 | false(0) | true(1) |
Float16 / нет | 16 | Половинная точность | |
Float32 / single | 32/32 | Одинарная точность | |
Float64 / double | 64/64 | Двойная точность | |
(Nifj или Qifj) / fi(i,x,n,m) | (min 8, max 64) / (min 1, max 1024) | Число с фиксированной запятой |
Объявления типа¶
Оператор ::
можно использовать для присоединения аннотаций типов к выражениям и переменным в программах. Есть две основные причины сделать это.
- В качестве установки, помогающей подтвердить, что ваша программа работает так, как вы ожидаете.
- Чтобы предоставить компилятору дополнительную информацию о типе, и в некоторых случаях это может повысить производительность.
При добавлении к выражению, вычисляющему значение, ::
оператор читается как «является экземпляром».
(1+2)::Int
При добавлении к переменной в левой части присваивания ::
объявляет, что переменная всегда имеет указанный тип, подобно объявлению типа в статически типизированном языке, таком, как C.
function foo()
x::Int8 = 100
end
x = foo()
typeof(x)
Эта функция полезна для предотвращения проблем с производительностью, которые могут возникнуть, если одно из присвоений переменной неожиданно изменило ее тип.
Такое поведение «объявления» происходит только в определенных контекстах и применяется ко всей текущей области действия, даже до объявления.
local x::Int8 # in a local declaration
Также объявления типов можно применить к глобальным переменным.
a::Int = 10
typeof(a)
function foo(y)
global a = 15 # throws an error when foo is called
return a + y
end
foo(10)
Объявления могут быть прикреплены и к определениям функций:
function sinc(x)::Float64
if x == 0
return 1
end
return sin(pi*x)/(pi*x)
end
sinc(1.1)
Абстрактные типы¶
Абстрактные типы не могут быть созданы и служат только узлами в графе типов, описывая тем самым наборы связанных конкретных типов, которые являются их потомками.
abstract type Pointy{T} end
Pointy{Int64} <: Pointy
Pointy{1} <: Pointy
Pointy{Float64} <: Pointy{Real}
Типы кортежей¶
Кортежи — это абстракция аргументов функции без самой функции. Важнейшими аспектами аргументов функции являются их порядок и типы. Поэтому тип кортежа аналогичен параметризованному неизменяемому типу, где каждый параметр является типом одного поля. Например, тип кортежа из двух элементов похож на следующий неизменяемый тип:
struct Tuple2{A,B}
a::A
b::B
end
Однако есть три ключевых отличия:
- Типы кортежей могут иметь любое количество параметров.
- Типы кортежей ковариантны по своим параметрам:
Tuple{Int}
является подтипомTuple{Any}
. ПоэтомуTuple{Any}
считается абстрактным типом, а типы кортежей являются конкретными только в том случае, если их параметры являются конкретными. - Кортежи не имеют имен полей; доступ к полям осуществляется только по индексу.
Значения кортежа записываются в круглых скобках и запятых. При построении кортежа соответствующий тип кортежа генерируется по требованию:
typeof((1,"foo",2.5))
Tuple{Int64, String, Float64}
Tuple{Int,AbstractString} <: Tuple{Real,Any}
Tuple{Int,AbstractString} <: Tuple{Real,Real}
Типы кортежей Vararg¶
Последним параметром типа кортежа может быть специальное значение Vararg
, обозначающее любое количество конечных элементов:
mytupletype = Tuple{AbstractString,Vararg{Int}}
Tuple{AbstractString, Vararg{Int64}}
isa(("1",1,2), mytupletype)
isa(("1",1,2,3.0), mytupletype)
Именованные кортежи¶
Именованные кортежи — это экземпляры типа NamedTuple
, который имеет два параметра: кортеж символов, задающий имена полей, и тип кортежа, задающий типы полей. Для удобства NamedTuple
типы выводятся с помощью @NamedTuple
макроса.
typeof((a=1,b="hello")) # prints in macro form
@NamedTuple{a::Int64, b::String}
Параметрические примитивные типы¶
Примитивные типы тоже можно объявлять параметрически. Например, указатели представлены как примитивные типы, которые будут объявлены в Julia следующим образом:
# 64-bit system:
primitive type P{T} 64 end
P{Int64} <: P
P{Float64} <: P
Вывод¶
В данной демонстрации показаны основные типы данных, а также возможности их объявления и применения. Дополнительную информацию можно посмотреть в статьях про целые числа и числа с плавающей запятой, а также в статье про типы данных, на основе которых была реализована данная демонстрация.