如何限制函数参数的类型

Ano*_*non 4 type-inference switch-statement 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
Run Code Online (Sandbox Code Playgroud)

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

def encode(obj : Int32 | String | Symbol | Array)
Run Code Online (Sandbox Code Playgroud)

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

WPe*_*0EU 9

超载到救援:

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
Run Code Online (Sandbox Code Playgroud)