键入alias和Hash作为方法参数

时间:2017-09-07 20:55:45

标签: crystal-lang type-alias

我正在尝试为接收Hash作为参数的Class创建初始化程序。哈希是{String =>键入} hash,可以嵌套。我在运行此代码时遇到错误:

#file: types.cr
class Types
  alias Type = Nil |
               Bool |
               Int32 |
               Int64 |
               Float64 |
               String |
               Array(Type) |
               Hash(String, Type)

  def initialize(@input : Type)
  end
end

input = {"a" => {"b" => {"c" => {"c1" => 1, "c2" => 2, "c3" => true}}}}
s = Types.new(input)

以下是运行上述代码时出现的错误:

$ crystal types.cr

Error in types.cr:16: instantiating 'Types:Class#new(Hash(String, Hash(String, Hash(String, Hash(String, Bool | Int32)))))'

s = Types.new(input)
          ^~~

in types.cr:11: instance variable '@input' of Types must be Types::Type, not Hash(String, Hash(String, Hash(String, Hash(String, Bool | Int32))))

  def initialize(@input : Type)
                 ^~~~~~

水晶可以吗?我该怎么做呢?

谢谢!

1 个答案:

答案 0 :(得分:4)

您可以指定每个哈希的类型:

c = {"c1" => 1, "c2" => 2, "c3" => true} of String => Types::Type
b = {"c" => c} of String => Types::Type
a = {"b" => b} of String => Types::Type

t = Types.new({"a" => a} of String => Types::Type)
pp t # => #<Types:0x103085ec0
     #    @input=
     #      {"a" => {"b" => {"c" => {"c1" => 1, "c2" => 2, "c3" => true}}}}>

另一种方法是定义和使用Hash-like type

alias Type = Nil         |
             Bool        |
             Int32       |
             Int64       |
             Float64     |
             String      |
             Array(Type) |
             Hash(String, Type)

alias TypesHash = Hash(String, Type)

t = TypesHash{
  "a" => TypesHash{
    "b" => TypesHash{
      "c" => TypesHash{
        "c1" => 1, "c2" => 2, "c3" => true,
      },
    },
  },
}

t                                            # {"a" => {"b" => {"c" => {"c1" => 1, "c2" => 2, "c3" => true}}}}
t["a"]                                       # {"b" => {"c" => {"c1" => 1, "c2" => 2, "c3" => true}}}
t["a"].as(TypesHash)["b"]                    # {"c" => {"c1" => 1, "c2" => 2, "c3" => true}}
t["a"].as(TypesHash)["b"].as(TypesHash)["c"] # {"c1" => 1, "c2" => 2, "c3" => true}

所以你可以像TypesHash object:

一样将它传递给构造函数
class Types
  def initialize(@input : TypesHash); end
end

Types.new t