卷曲支架构造函数?

时间:2018-03-14 12:34:50

标签: crystal-lang

在阅读Crystal文档时,我遇到了这一行:

 deq = Deque{2, 3}

所以我认为这会调用Deque.new(array : Array(T))构造函数。但是,我没有找到任何关于此语法的文档。 (编辑The documentation can be found here

为了测试这种调用构造函数的方式,我编写了以下测试

class Foo(T)
  def initialize(@bar : Array(T)); end

  def to_s(io : IO)
    io << "Foo: "
    io << @bar
  end
end

puts Foo{1} # Line 10

但是,编译它会打印出这个错误:

Error in line 10: wrong number of arguments for 'Foo(Int32).new' (given 0, expected 1)
Overloads are:
 - Foo(T).new(bar : Array(T))

我真的根本不懂。 Foo(Int32){1}引发同样的错误。

问题是,这个Klass{1, 2, 3}语法是什么?你怎么用它?

2 个答案:

答案 0 :(得分:8)

这里记录了它们:https://crystal-lang.org/docs/syntax_and_semantics/literals/array.html

类似数组的类型文字

Crystal支持数组和类数组类型的附加文字。它由类型的名称后跟一个用大括号({})括起来的元素列表和用逗号(,)分隔的单个元素组成。

Array{1, 2, 3}

只要文字具有无定型构造函数并响应<<,该文字就可以用于任何类型。

IO::Memory{1, 2, 3}
Set{1, 2, 3}

对于像IO::Memory这样的非泛型类型,这相当于:

array_like = IO::Memory.new
array_like << 1
array_like << 2
array_like << 3

对于像Set这样的泛型类型,泛型类型T是以与数组文字相同的方式从元素类型推断出来的。以上相当于:

array_like = Set(typeof(1, 2, 3)).new
array_like << 1
array_like << 2
array_like << 3

可以将类型参数显式指定为类型名称的一部分:

Set(Number) {1, 2, 3}

答案 1 :(得分:3)

要创建这样的类型,您需要定义一个argless构造函数和#<<方法:

class Foo(T)
  def initialize
    @store = Array(T).new
  end

  def <<(elem : T)
    @store << elem
  end
end

foo = Foo(Int32){1, 2, 3}
p foo #=> #<Foo(Int32):0x103440b20 @store=[1, 2, 3]>