Spec-Zone.ru › Crystal

Присваивание

Выражение присваивания присваивает значение именованному идентификатору (обычно переменной). Оператор присваивания — это знак равенства (=).

Целью присваивания может быть:

  • локальная переменная
  • переменная экземпляра
  • переменная класса
  • константа
  • метод присваивания
# Assigns to a local variable
local = 1

# Assigns to an instance variable
@instance = 2

# Assigns to a class variable
@@class = 3

# Assigns to a constant
CONST = 4

# Assigns to a setter method
foo.method = 5
foo[0] = 6

Метод в качестве цели присваивания

Метод, имя которого заканчивается знаком равенства (=), называется методом-сеттером. Его можно использовать в качестве цели присваивания. Семантика оператора присваивания применяется как синтаксический сахар для вызова метода.

Для вызова методов-сеттеров требуется явный получатель. Синтаксис без получателя x = y всегда разбирается как присваивание локальной переменной, а не как вызов метода x=. Даже добавление скобок не заставляет интерпретировать выражение как вызов метода, как это происходит при чтении локальной переменной.

В следующем примере показаны два вызова метода-сеттера: в обычной записи метода и с оператором присваивания. Оба выражения присваивания эквивалентны.

class Thing
  def name=(value); end
end

thing = Thing.new

thing.name=("John")
thing.name = "John"

В следующем примере показаны два вызова метода индексированного присваивания: в обычной записи метода и с оператором индексированного присваивания. Оба выражения присваивания эквивалентны.

class List
  def []=(key, value); end
end

list = List.new

list.[]=(2, 3)
list[2] = 3

Составные присваивания

Составные присваивания сочетают оператор присваивания с другим оператором. Они работают с любым типом цели, кроме констант.

Доступен синтаксический сахар с символом =:

local += 1  # same as: local = local + 1

Предполагается, что соответствующей цели local можно присвоить значение — напрямую как переменной либо через соответствующие методы чтения и записи.

Синтаксический сахар для оператора = также доступен для методов-сеттеров и методов индексированного присваивания. Обратите внимание, что || и && используют метод []? для проверки наличия ключа.

person.age += 1 # same as: person.age = person.age + 1

person.name ||= "John" # same as: person.name || (person.name = "John")
person.name &&= "John" # same as: person.name && (person.name = "John")

objects[1] += 2 # same as: objects[1] = objects[1] + 2

objects[1] ||= 2 # same as: objects[1]? || (objects[1] = 2)
objects[1] &&= 2 # same as: objects[1]? && (objects[1] = 2)

Цепочечное присваивание

Одно и то же значение можно присвоить нескольким целям с помощью цепочечного присваивания. Оно работает с любым типом цели, кроме констант.

a = b = c = 123

# Now a, b and c have the same value:
a # => 123
b # => 123
c # => 123

Множественное присваивание

Можно объявить или присвоить значения нескольким переменным одновременно, разделив выражения запятой (,). Это работает с любым типом цели, кроме констант.

name, age = "Crystal", 1

# The above is the same as this:
temp1 = "Crystal"
temp2 = 1
name = temp1
age = temp2

Поскольку выражения присваиваются временным переменным, содержимое переменных можно обменять в одной строке:

a = 1
b = 2
a, b = b, a
a # => 2
b # => 1

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

name, age, source = "Crystal, 123, GitHub".split(", ")

# The above is the same as this:
temp = "Crystal, 123, GitHub".split(", ")
name = temp[0]
age = temp[1]
source = temp[2]

Множественное присваивание также доступно для методов, заканчивающихся на =:

person.name, person.age = "John", 32

# Same as:
temp1 = "John"
temp2 = 32
person.name = temp1
person.age = temp2

Оно также доступно для индексированных присваиваний ([]=):

objects[1], objects[2] = 3, 4

# Same as:
temp1 = 3
temp2 = 4
objects[1] = temp1
objects[2] = temp2

Подчёркивание

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

_ = 1     # no effect
_ = "123" # no effect
puts _    # Error: can't read from _

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

before, _, after = "main.cr".partition(".")

# The above is the same as this:
temp = "main.cr".partition(".")
before = temp[0]
_ = temp[1] # this line has no effect
after = temp[2]

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

Spec-Zone.ru

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