Как получить и использовать тип, выведенный из общего - PullRequest
0 голосов
/ 23 октября 2018

В следующем примере, я полагаю, мне приходится иметь дело с типом Enumerable некоторых структур данных, заполненных литералами:

module TestGenerics
  class Foo(T)
    include Enumerable(T)

    def initialize(@data : T)
      typeof(@data)
      typeof(@data.first)
    end
  end
  Foo.new(1..3)
  Foo.new([1, 'A', 3.14])
  Foo.new([[1, 'A', 3.14], [2, 'Z', 9.99]])
  Foo.new({"A" => [1, 'A', 3.14], "B" => [2, 'Z', 9.99]})
end

Для каждого экземпляра класса Foo typeof (@data) дает:

  1. Диапазон (Int32, Int32)

  2. Массив (Char | Float64 | Int32)

  3. Array (Array (Char | Float64 | Int32))

  4. Hash (String, Array (Char | Float64 | Int32))

иtypeof (@ data.first) дает:

  1. Int32
  2. (Char | Float64 | Int32)
  3. Array (Char | Float64 | Int32)
  4. Tuple (String, Array (Char | Float64 | Int32))

Это хорошо, но теперь моя проблема: как я могу использовать любой из этих предполагаемых типов с помощью Crystal Compiler в другой частимоего кода?Или это вообще невозможно?!

Спасибо

[РЕДАКТИРОВАТЬ] Мой вопрос возник из моего проекта по адаптации личного приложения, написанного на Ruby, к языку Crystal (который я открываю).Это приложение использует Ruby Gem Tabulo (https://github.com/matt-harvey/tabulo),, поэтому я пытаюсь также адаптировать этот Gem к языку Crystal.

Этот Ruby Gem предназначен для форматирования таблиц данных (фактически, любого типа перечислимогоструктура данных), определяя столбцы для отображения. Это делается с помощью функции «add_column», которая имеет среди своих параметров различные атрибуты форматирования и, что более важно, блок для доступа к базовым данным на уровне «строки» (чей тип задан typeof (@ data.first) в примере кода). Я сделал адаптацию, взяв определенный тип данных: Array (Array (Float64)). Он работает, и теперь моя цель - сделать эту адаптациюуниверсальный, вероятно, потребует любого ввода Enumerable данных, как показано в приведенном выше примере кода.

Итак, насколько мои (плохие) навыки позволяют мне понять, как работает Crystal в этом случае, мне нужноиспользуйте тип данных, определенный входной структурой данных.

Извините, если в этом объяснении не хватает деталей, но логика Tabulo Gem не подходитСложно, и довольно сложно обобщить в нескольких словах.В любом случае, спасибо за вашу помощь.

1 Ответ

0 голосов
/ 26 октября 2018

Так что мне все еще трудно понять, что вы пытаетесь сделать.Если вы хотите ветвиться в зависимости от типа, вы можете использовать case.

var = 5
var = 5..10 if Random.rand > 0.5
case var
when Int32
  puts "int inside here"
when Range(Int32, Int32)
  puts "range inside here"
end

Может быть, вы ищете Enumerable , который дает набор методов, которые можно использовать для всех различных типов?

enumerable = [1,5,6]
enumerable = {2,7,8} if Random.rand > 0.5
# Draw top of table
# #each is defined from Enumerable, so is available to both Array and Tuple
enumerable.each do |val|
  puts "|#{val}|"
end
# Draw end of table
...