2017-09-17 45 views
4

考慮下面的代碼:嵌套哈希生成錯誤

require "big" 

alias Type = Nil | String | Bool | Int32 | BigFloat | Array(Type) | Hash(String | Symbol, Type) 
alias HOpts = Hash(String | Symbol, Type) 

ctx = HOpts.new 
ctx["test_int"] = 1 
ctx["test_s"] = "hello" 

c1 = Hash(String, Type).new 
ctx["stuff"] = c1 
ctx["stuff"]["foo"] = { "bar" => 1 } 

我得到:

Error in test.cr:13: instantiating 'Hash(String | Symbol, Type)#[]=(String, Hash(String, Type))' 

ctx["stuff"] = c1 
^

in /opt/crystal/src/hash.cr:43: instantiating 'insert_in_bucket(Int32, String, Hash(String, Type))' 

    entry = insert_in_bucket index, key, value 
      ^~~~~~~~~~~~~~~~ 

in /opt/crystal/src/hash.cr:842: instantiating 'Hash::Entry(String | Symbol, Type)#value=(Hash(String, Type))' 

      entry.value = value 
       ^~~~~ 

in /opt/crystal/src/hash.cr:881: expanding macro 

    property value : V 
    ^

in macro 'property' expanded macro: macro_83313872:567, line 10: 

    1.  
    2.   
    3.   
    4.    @value : V 
    5. 
    6.    def value : V 
    7.    @value 
    8.    end 
    9. 
> 10.    def value=(@value : V) 
    11.    end 
    12.   
    13.   
    14.  
    15.  

instance variable '@value' of Hash::Entry(String | Symbol, Type) must be Type, not Hash(String, Type) 

我希望能夠創建任何類型的嵌套哈希的,但它不工作。

回答

3

這裏有一些錯誤。

c1的類型是Hash(String, Type)這不是Type聯合的類型之一。 Hash(String, Type)Hash(String | Symbol, Type)不兼容。

無論是包括Hash(String, Type)Type工會,或給予c1類型Hash(String | Symbol, Type)(即HOpts):

c1 = HOpts.new 

您也將有這行代碼另一個錯誤:

ctx["stuff"]["foo"] = { "bar" => 1 } 

ctx["stuff"]將返回類型爲Type的對象,而不是您希望的哈希。如果你知道ctx["stuff"]是一個散列(我們從這個例子中做的),那麼你需要限制它的類型。此外{ "bar" => 1 }Hash(String, Int32)型的,而不是Hash(String, Type),所以你需要太指定此:

ctx["stuff"].as(HOpts)["foo"] = HOpts{ "bar" => 1 } 
+0

非常感謝您 – binduck

+0

這是更好地使用',而不是'哈希HOpts'別名(字符串|符號,類型)'無處不在,所以在更改類型時不需要更新它。即'HOpts.new'和'ctx [「stuff」]。作爲(HOpts)' –

+0

@VitaliiElenhaupt啊,當然是編輯。 –