Spec-Zone.ru › Crystal

Обобщения

Обобщения позволяют параметризовать тип на основе другого типа. Рассмотрим тип Box:

class MyBox(T)
  def initialize(@value : T)
  end

  def value
    @value
  end
end

int_box = MyBox(Int32).new(1)
int_box.value # => 1 (Int32)

string_box = MyBox(String).new("hello")
string_box.value # => "hello" (String)

another_box = MyBox(String).new(1) # Error, Int32 doesn't match String

Обобщения особенно полезны при реализации типов коллекций. Array, Hash, Set — обобщённые типы, как и Pointer.

Можно указать несколько параметров типа:

class MyDictionary(K, V)
end

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

class MyDictionary(KeyType, ValueType)
end

Выведение переменных типа

Ограничения типа в конструкторе обобщённого типа являются свободными переменными, если аргументы типа не указаны, после чего используются для их выведения. Например:

MyBox.new(1)       # : MyBox(Int32)
MyBox.new("hello") # : MyBox(String)

В приведённом выше коде нам не пришлось указывать аргументы типа для MyBox: компилятор вывел их следующим образом:

  • MyBox.new(value) делегирует initialize(@value : T)
  • T ещё не привязана к типу, поэтому компилятор связывает её с типом переданного аргумента

Так с обобщёнными типами работать проще.

Обобщённые структуры и модули

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

module Moo(T)
  def t
    T
  end
end

class Foo(U)
  include Moo(U)

  def initialize(@value : U)
  end
end

foo = Foo.new(1)
foo.t # Int32

Обратите внимание: в приведённом выше примере T становится Int32, поскольку Foo.new(1) превращает U в Int32, что, в свою очередь, превращает T в Int32 при подключении обобщённого модуля.

Наследование обобщённых типов

От обобщённых классов и структур можно наследоваться. При наследовании можно указать экземпляр обобщённого типа или делегировать переменные типа:

class Parent(T)
end

class Int32Child < Parent(Int32)
end

class GenericChild(T) < Parent(T)
end

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

Spec-Zone.ru

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