2017-09-07 7 views
3

パラメータとしてHashを受け取るClassの初期化子を作成しようとしています。ハッシュは{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 
関連する問題