Spec-Zone.ru › Crystal

Массив

Массив — это упорядоченная обобщённая коллекция элементов определённого типа T, индексируемая целыми числами.

Массивы обычно создаются с помощью литерала массива, заключённого в квадратные скобки ([]), а отдельные элементы разделяются запятыми (,).

[1, 2, 3]

Аргумент обобщённого типа

Аргумент обобщённого типа массива T выводится из типов элементов внутри литерала. Если все элементы массива имеют одинаковый тип, T принимает это значение. В противном случае он будет объединением типов всех элементов.

[1, 2, 3]         # => Array(Int32)
[1, "hello", 'x'] # => Array(Int32 | String | Char)

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

array_of_numbers = [1, 2, 3] of Float64 | Int32 # => Array(Float64 | Int32)
array_of_numbers << 0.5                         # => [1, 2, 3, 0.5]

array_of_int_or_string = [1, 2, 3] of Int32 | String # => Array(Int32 | String)
array_of_int_or_string << "foo"                      # => [1, 2, 3, "foo"]

Для литералов пустых массивов всегда требуется указать тип:

[] of Int32 # => Array(Int32).new

Литералы массивов с процентной нотацией

Массивы строк и массивы символов можно создавать с помощью литералов массивов с процентной нотацией:

%w(one two three) # => ["one", "two", "three"]
%i(one two three) # => [:one, :two, :three]

Литерал типа, подобного массиву

Crystal поддерживает дополнительный литерал для массивов и типов, подобных массивам. Он состоит из имени типа, за которым следует список элементов в фигурных скобках ({}); отдельные элементы разделяются запятыми (,).

Array{1, 2, 3}

Этот литерал можно использовать с любым типом, если у него есть конструктор без аргументов и он отвечает на <<.

IO::Memory{1, 2, 3}
Set{1, 2, 3}

Для необобщённого типа, такого как IO::Memory, это эквивалентно следующему:

array_like = IO::Memory.new
array_like << 1
array_like << 2
array_like << 3

Для обобщённого типа, такого как Set, обобщённый тип T выводится из типов элементов так же, как и для литерала массива. Приведённое выше эквивалентно следующему:

array_like = Set(typeof(1, 2, 3)).new
array_like << 1
array_like << 2
array_like << 3

Аргументы типов можно указать явно в составе имени типа:

Set(Int32){1, 2, 3}

Раскрытие оператора splat

Оператор splat можно использовать в литералах массивов и типов, подобных массивам, чтобы сразу вставить несколько значений.

[1, *coll, 2, 3]
Set{1, *coll, 2, 3}

Единственное требование — тип coll должен включать Enumerable. Приведённое выше эквивалентно следующему:

array = Array(typeof(...)).new
array << 1
array.concat(coll)
array << 2
array << 3

array_like = Set(typeof(...)).new
array_like << 1
coll.each do |elem|
  array_like << elem
end
array_like << 2
array_like << 3

В этих случаях аргумент обобщённого типа дополнительно выводится с учётом элементов coll.

To the extent possible under law, the persons who contributed to this workhave waived
all copyright and related or neighboring rights to this workby associating CC0 with it.
https://crystal-lang.org/reference/1.2/syntax_and_semantics/literals/array.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API