如何限制函数参数的类型

时间:2018-05-09 17:57:42

标签: switch-statement type-inference crystal-lang

我们说我有以下功能:

def encode(obj)
  case obj
  when Int32
    "i#{obj}e"
  when String
    "#{obj.size}:#{obj}"
  when Symbol
    encode(obj.to_s)
  when Array
    obj.reduce "a" {|acc, i| acc + encode(i)} + "e"
  else
    raise ArgumentError.new "Cannot encode argument of class '#{obj.class}'"
  end
end

我想摆脱那个else分支,对参数的类型进行编译时检查。我可以这样写:

def encode(obj : Int32 | String | Symbol | Array)

在这种情况下,没关系。但是,如果有更大的类型列表呢?有没有更优雅的方式来做到这一点?我希望编译器检查此函数是否只接受case表达式中匹配的那些类型。

1 个答案:

答案 0 :(得分:9)

Overloading救援:

def encode(obj : Int32)
  "i#{obj}e"
end

def encode(obj : String)
  "#{obj.size}:#{obj}"
end

def encode(obj : Symbol)
  encode(obj.to_s)
end

def encode(obj : Array(String))
  obj.reduce "a" { |acc, i| acc + encode(i) } + "e"
end