为什么红宝石添加不能强制给定字符串到fixnum,反之亦然?
irb>fixnum = 1
=> 1
irb> fixnum.class
=> Fixnum
irb> string = "3"
=> "3"
irb> string.class
=> String
irb> string.to_i
=> 3
irb> fixnum + string
TypeError: String can't be coerced into Fixnum
from (irb):96:in `+'
from (irb):96
from :0
irb(main):097:0>
答案 0 :(得分:10)
因为ruby不知道您是要将字符串转换为int还是将int转换为字符串。在例如java 1 + "3"
是"13"
。 Ruby更喜欢引发错误,以便用户可以决定是to_s
一个操作数还是to_i
另一个操作数,而不是自动做错事。
答案 1 :(得分:5)
它吐出错误,因为红宝石不知道你想要什么。 String + fixnum是一个含糊不清的语句。它可能意味着您要添加字符串的int值和数字,或者int和字符串的字符串值。例如:
str = "5"
num = 3
puts str.to_i + num
=> 8
puts str + num.to_s
=> 53
而不是猜测你想要哪一个,ruby只是抛出异常。
答案 2 :(得分:1)
您需要将变量设置回自身,因为执行.to_i
会返回一个整数值,但不会修改原始对象。
>> string = "3"
=> "3"
>> string.class
=> String
>> string.to_i
=> 3
>> string
=> "3"
>> string.class
=> String
>> string = string.to_i
=> 3
>> string.class
=> Fixnum
答案 3 :(得分:1)
Fixnum#+
只是一种方法。简化它的工作原理如下:
class Fixnum
def +(other)
if Fixnum === other
# normal operation
else
n1, n2= other.coerce(self)
return n1+n2
end
end
end
coerce
用于自动数字类型转换。例如,如果您执行42 + 3.141
,则会使用此选项。 ruby中的字符串不能自动转换为数值。您可以增强String
类以便能够执行此操作。你只需要做
class String
def coerce(other)
coerced= case other
when Integer
self.to_i
when
self.to_f
end
return coerced, other
end
end
现在你可以做到
23 + "42" # => 65
0.859 - "4" # => 3.141
这不是另一种方式。 coerce
仅适用于数字值"23" + 42
不起作用。 String#+
不会使用强制。
简化+
已在Fixnum
中完成,而不是故意在Integer
中完成。 Fixnum
和Bignum
有各自不同的方法,因为它们在内部的工作方式非常不同。