Spec-Zone.ru › Crystal

Операторы распаковки и кортежи

Метод может принимать переменное число аргументов с помощью параметра с оператором распаковки (*), который может встречаться только один раз и в любой позиции:

def sum(*elements)
  total = 0
  elements.each do |value|
    total += value
  end
  total
end

sum 1, 2, 3      # => 6
sum 1, 2, 3, 4.5 # => 10.5

Переданные аргументы становятся кортежем в теле метода:

# elements is Tuple(Int32, Int32, Int32)
sum 1, 2, 3

# elements is Tuple(Int32, Int32, Int32, Float64)
sum 1, 2, 3, 4.5

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

def sum(*elements, initial = 0)
  total = initial
  elements.each do |value|
    total += value
  end
  total
end

sum 1, 2, 3              # => 6
sum 1, 2, 3, initial: 10 # => 16

Параметры, следующие за параметром с оператором распаковки и не имеющие значения по умолчанию, являются обязательными именованными параметрами:

def sum(*elements, initial)
  total = initial
  elements.each do |value|
    total += value
  end
  total
end

sum 1, 2, 3              # Error, missing argument: initial
sum 1, 2, 3, initial: 10 # => 16

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

def foo(*elements, x)
  1
end

def foo(*elements, y)
  2
end

foo x: "something" # => 1
foo y: "something" # => 2

Параметр с оператором распаковки также можно оставить без имени — это означает, что после него следуют именованные параметры:

def foo(x, y, *, z)
end

foo 1, 2, 3    # Error, wrong number of arguments (given 3, expected 2)
foo 1, 2       # Error, missing argument: z
foo 1, 2, z: 3 # OK

Распаковка кортежа

Tuple можно распаковать в вызов метода с помощью *:

def foo(x, y)
  x + y
end

tuple = {1, 2}
foo *tuple # => 3

Двойная распаковка и именованные кортежи

Двойная распаковка (**) захватывает именованные аргументы, которые не были сопоставлены с другими параметрами. Тип параметра — NamedTuple:

def foo(x, **other)
  # Return the captured named arguments as a NamedTuple
  other
end

foo 1, y: 2, z: 3    # => {y: 2, z: 3}
foo y: 2, x: 1, z: 3 # => {y: 2, z: 3}

Двойная распаковка именованного кортежа

NamedTuple можно распаковать в вызов метода с помощью **:

def foo(x, y)
  x - y
end

tuple = {y: 3, x: 10}
foo **tuple # => 7

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/splats_and_tuples.html

Spec-Zone.ru

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