如何限制函数参数的类型

How to restrict type of a function argument

假设我有以下功能:

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 表达式中匹配的那些类型。

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