2017-09-07 57 views
3

我正在尝试为接收散列作为参数的类创建初始化程序。散列是一个{String => Type}散列,并且可以嵌套。键入别名和散列作为方法参数

#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) 
       ^~~~~~ 

这可能与水晶运行此代码时,我得到一个错误?我应该如何处理这个问题?

谢谢!

回答

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对象:

class Types 
    def initialize(@input : TypesHash); end 
end 

Types.new t