5

我不确定我传递给方法的对象是否是正确的类型。我可能会将字符串传递给只能处理整数的函数。某种运行时保证呢?我找不到比以下更好的选择:

def someFixNumMangler(input)
  raise "wrong type: integer required" unless input.class == FixNum
  other_stuff
end

有更好的选择吗?

4

2 回答 2

5

在使用之前使用Kernel#Integer方法转换输入。ArgumentError当输入无法以任何合理的方式转换为整数时,它将引发。

def my_method(number)
  number = Integer(number)
  # do something with number, which is now guaranteed to be an integer
end

我推荐 Avdi Grimm 的新书Confident Ruby以更深入地了解这一点。

于 2013-09-05T13:11:18.820 回答
3

如果您确实需要进行类型检查,那么是的,您只有运行时检查。问题中的代码没问题。您也可以使用.is_a?.

def someFixNumMangler(input)
  raise "wrong type: integer required" unless input.is_a?(FixNum)
  other_stuff
end

支票可能采用不同的形式。例如,如果您期望一个字符串并在其上调用字符串方法(upcasegsub等),那么如果传递了字符串以外的任何内容,则代码将崩溃。当然,除非您传递的对象不是字符串,但其行为就像一个对象(具有您调用的相同方法)。这就是鸭式打字的精髓。

如果你的方法看起来像这样呢?

def someFixNumMangler(input)
  input = input.to_i
  puts "got this: #{input} of #{input.class}"
end


someFixNumMangler(10)
someFixNumMangler('42')
someFixNumMangler(File)

# >> got this: 10 of Fixnum
# >> got this: 42 of Fixnum
# ~> -:2:in `someFixNumMangler': undefined method `to_i' for File:Class (NoMethodError)
# ~>    from -:9:in `<main>'

只要参数响应#to_i,您实际上并不关心它的类型是什么。

于 2013-09-05T12:59:26.430 回答