【问题标题】:Type alias and Hash as method parameter键入别名和哈希作为方法参数
【发布时间】:2017-09-07 20:55:45
【问题描述】:

我正在尝试为接收哈希作为参数的类创建一个初始化程序。哈希是一个 {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)
                 ^~~~~~

Crystal 可以做到这一点吗?我应该如何处理?

谢谢!

【问题讨论】:

    标签: crystal-lang type-alias


    【解决方案1】:

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

    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
    

    【讨论】:

      猜你喜欢
      • 2011-07-01
      • 2018-09-15
      • 2014-05-19
      • 1970-01-01
      • 2013-02-24
      • 1970-01-01
      • 1970-01-01
      • 2011-02-05
      • 2011-12-03
      相关资源
      最近更新 更多