【问题标题】:Curly bracket constructors?花括号构造函数?
【发布时间】:2018-03-14 12:34:49
【问题描述】:

在阅读 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} 语法是什么?以及如何使用它?

【问题讨论】:

    标签: crystal-lang


    【解决方案1】:

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


    类数组字面量

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

    Array{1, 2, 3}
    

    这个字面量可以与任何类型一起使用,只要它有一个无参数的构造函数并响应&lt;&lt;

    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}
    

    【讨论】:

      【解决方案2】:

      要创建这样的类型,您需要定义一个无参数构造器和#&lt;&lt; 方法:

      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]>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-05-28
        • 2023-03-05
        • 1970-01-01
        • 2016-09-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多