如何获取和使用从泛型推断的类型

Posted

技术标签:

【中文标题】如何获取和使用从泛型推断的类型【英文标题】:How to get and use type inferred from generic 【发布时间】:2019-03-28 04:24:57 【问题描述】:

在下面的例子中,我想我必须处理一些数据结构的 Enumerable 类型,由 litterals 填充:

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) 给出:

    范围(Int32,Int32)

    数组(Char | Float64 | Int32)

    Array(Array(Char | Float64 | Int32))

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

并且 typeof(@data.first) 给出:

    Int32 (Char | Float64 | Int32) 数组(Char | Float64 | Int32) 元组(字符串,数组(Char | Float64 | Int32))

很好,但现在,我的问题是:如何在我的代码的其他部分使用 Crystal 编译器推断的任何这些类型?还是根本不可能?!

谢谢

[编辑] 我的问题源于我的项目,以使用 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 在这种情况下是如何工作的而言,我需要使用输入数据结构定义的数据类型。

对不起,如果这个解释有点缺乏细节,但禁忌宝石的逻辑相当复杂,很难用几句话来概括。 无论如何,感谢您的帮助。

【问题讨论】:

你想对这些类型做什么?不然给你回复有点难…… 请看原文编辑 【参考方案1】:

所以我仍然很难理解你想要做什么。如果要根据类型进行分支,可以使用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

【讨论】:

以上是关于如何获取和使用从泛型推断的类型的主要内容,如果未能解决你的问题,请参考以下文章

从泛型问题推断

Scala - 从泛型类型获取类对象

如何在 Spring Boot 中从泛型参数(与任何类无关)中获取值

如何在 Kotlin 中获取泛型类型参数的类

从泛型类型快速实例化

我可以在 C# 中从泛型类型转换为枚举吗?