Spec-Zone.ru › Crystal

Методы и переменные экземпляра

Мы можем упростить конструктор, используя сокращённый синтаксис для присваивания параметра метода переменной экземпляра:

class Person
  def initialize(@name : String)
    @age = 0
  end

  def age
    @age
  end
end

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

class Person
  def initialize(@name : String)
    @age = 0
  end

  def age
    @age
  end

  def become_older
    @age += 1
  end
end

john = Person.new "John"
peter = Person.new "Peter"

john.age # => 0

john.become_older
john.age # => 1

peter.age # => 0

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

Геттеры и сеттеры

Стандартная библиотека Crystal предоставляет макросы, упрощающие определение методов-геттеров и методов-сеттеров:

class Person
  property age
  getter name : String

  def initialize(@name)
    @age = 0
  end
end

john = Person.new "John"
john.age = 32
john.age # => 32

Подробнее о макросах геттеров и сеттеров см. в документации стандартной библиотеки: Object#getter, Object#setter и Object#property.

К слову, мы можем определить become_older внутри исходного определения Person или в отдельном определении: Crystal объединяет все определения в один класс. Следующий вариант работает без проблем:

class Person
  def initialize(@name : String)
    @age = 0
  end
end

class Person
  def become_older
    @age += 1
  end
end

Переопределение методов и previous_def

При переопределении метода приоритет имеет последнее определение.

class Person
  def become_older
    @age += 1
  end
end

class Person
  def become_older
    @age += 2
  end
end

person = Person.new "John"
person.become_older
person.age # => 2

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

class Person
  def become_older
    @age += 1
  end
end

class Person
  def become_older
    previous_def
    @age += 2
  end
end

person = Person.new "John"
person.become_older
person.age # => 3

Если не передавать аргументы и не использовать скобки, previous_def получит все параметры метода в качестве аргументов. В противном случае он получит переданные ему аргументы.

Универсальная инициализация

Переменные экземпляра также можно инициализировать вне методов initialize:

class Person
  @age = 0

  def initialize(@name : String)
  end
end

Так переменная @age будет инициализирована нулём в каждом конструкторе. Это позволяет избежать дублирования кода, а также типа Nil при повторном открытии класса и добавлении в него переменных экземпляра.

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

Spec-Zone.ru

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