2017-09-07 80 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