Make类型Array(T)的Class成员属性接受T的2D数组

时间:2016-12-22 21:02:20

标签: crystal-lang

我已经定义了一个Container类。在@values属性中,我需要存储数组或2D数组,这些数组中的元素可以是Int32或Float64。如果我像这样初始化它:

class Container

  def initialize(value) 
    @values = values
  end

end

我收到错误:@values : Type, is inferred from assignments to it across the whole program.

如果我这样定义:

class Container

  def initialize(value : Array) 
    @values = values
  end

end

我得到:can't use Array(T) as the type of instance variable @values of Container(T), use a more specific type

如何让这个课程更加灵活,我可以这样做:

Container.new([1,2,3])
Container.new([1.0, 3.0, 4.0])
Container.new([[1, 2], [4,3,2],[1]])
Container.new([[1.0, 4.5], [2.2, 0.0]])

2 个答案:

答案 0 :(得分:2)

在进行一些挖掘之后,似乎确实存在official way of doing this。但是,必须对其进行规划,因为在构造函数中使用该语法从Crystal 0.20.1

开始提供以下内容
def initialize(value : Array(Array | Int32 | Float64))
    @values = value
end

Error in line 3: can't use Array(T) in unions yet, use a more specific type

如果我从您的示例数据中正确理解,似乎类型将是同类的(即数组将始终包含一种特定类型)。如果是这种情况,您可以简单地重载构造函数。它不是一个漂亮的解决方案,但它可能会让你束手无策。

class Container

  def initialize(value : Array(Array)) 
    @values = value
    calculate
  end

  def initialize(value : Array(Int32))
    @values = value
    calculate
  end

  def initialize(value : Array(Array(Int32)))
    @values = value
    calculate
  end

  def initialize(value : Array(Array(Float64)))
    @values = value
    calculate
  end

  def initialize(value : Array(Float64))
    @values = value
    calculate
  end

  def calculate
    # do stuff here
  end

end

Container.new([1,2,3])
Container.new([1.0, 3.0, 4.0])
Container.new([[1, 2], [4,3,2],[1]])
Container.new([[1.0, 4.5], [2.2, 0.0]])

修改

由于@Sija的评论,似乎你可以使用@ faaq的解决方案而不指定类型。他们还共享this sample code,我认为它比重载构造函数要清晰得多。

答案 1 :(得分:1)

为什么不使用泛型?

class Container(Type)

  def initialize(@values : Type) 
    pp @values
    pp typeof(@values)
  end

end

value = [1,2,3]
Container(typeof(value)).new(value)
value = [1.0, 3.0, 4.0]
Container(typeof(value)).new(value)
value = [[1, 2], [4,3,2],[1]]
Container(typeof(value)).new(value)
value = [[1.0, 4.5], [2.2, 0.0]]
Container(typeof(value)).new(value)

输出结果为:

@values # => [1, 2, 3]
typeof(@values) # => Array(Int32)
@values # => [1.0, 3.0, 4.0]
typeof(@values) # => Array(Float64)
@values # => [[1, 2], [4, 3, 2], [1]]
typeof(@values) # => Array(Array(Int32))
@values # => [[1.0, 4.5], [2.2, 0.0]]
typeof(@values) # => Array(Array(Float64))