本博客系列翻译自 Bigbinary 的 Ruby 2.6 系列, 已得到作者允许。Ruby 2.6.0-preview2 现已发布。
We can use Integer and Float methods to convert values to integers and floats respectively. Ruby also has to_i and to_f methods for same purpose. Let’s see how it differs from the Integer method.
我们可以使用 Integer 和 Float 方法各自来转换值为整形或者浮点型。当然,你也可以用 to_i 或者 to_f 来达到这一目的。我们来看看这写方法的异同:
>> "1one".to_i
=> 1
>> Integer("1one")
ArgumentError: invalid value for Integer(): "1one"
from (irb):2:in `Integer'
from (irb):2
from /Users/prathamesh/.rbenv/versions/2.4.0/bin/irb:11:in `<main>'
>>
to_i 方法会尝试尽可能地做到转换,然而Integer 方法会因为无法转换输入为整形而抛出异常。Float 和 to_f 方法也是同理。
有些时候,我们可能会严格地要求结果为整形或者浮点,但是又不愿意我们无法转换的时候会抛出异常。
在 Ruby 2.6之前我们会这样来达到目标:
>> Integer("msg") rescue nil
Ruby 2.6 Integer 和 Float 方法允许接受 exception 这一个参数内容,值为 true 或者 false。 如果是 false 那么它就只会返回nil 而且不抛出异常。
>> Float("foo", exception: false)
=> nil
>> Integer("foo", exception: false)
=> nil
这比早前版本的异常处理再返回nil 要快不少。
>> Benchmark.ips do |x|
?> x.report("rescue") {
?> Integer('foo') rescue nil
>> }
>> x.report("kwarg") {
?> Integer('foo', exception: false)
>> }
>> x.compare!
>> end
Warming up --------------------------------------
rescue 41.896k i/100ms
kwarg 81.459k i/100ms
Calculating -------------------------------------
rescue 488.006k (± 4.5%) i/s - 2.472M in 5.076848s
kwarg 1.024M (±11.8%) i/s - 5.050M in 5.024937s
Comparison:
kwarg: 1023555.3 i/s
rescue: 488006.0 i/s - 2.10x slower
如我们所见,过去的处理异常法会比新特性返回慢一倍。但如果需要返回自己想要设置的值而不是nil,我们仍可以继续用过去的实践方式。
>> Integer('foo') rescue 42
=> 42
默认的,这个exception 还会是true,为了向后兼容。