在Web编程中,数字通常出现为字符串形式。但是to_i
会将"5abc"
转换为5
,而将"abc"
转换为0
,这两个结果都是错误的。为了避免这种情况,我写了以下代码:
def number_or_nil( s )
number = s.to_i
number = nil if (number.to_s != s)
return number
end
有没有更简洁、更符合 Ruby 自然方式的方法来完成这种转换,并检测该字符串并非意图作为数字?
在Web编程中,数字通常出现为字符串形式。但是to_i
会将"5abc"
转换为5
,而将"abc"
转换为0
,这两个结果都是错误的。为了避免这种情况,我写了以下代码:
def number_or_nil( s )
number = s.to_i
number = nil if (number.to_s != s)
return number
end
有没有更简洁、更符合 Ruby 自然方式的方法来完成这种转换,并检测该字符串并非意图作为数字?
使用 Integer(string)。
如果字符串无法转换为整数,它将引发 ArgumentError 错误。
Integer('5abc') #=> ArgumentError: invalid value for Integer(): "5abc"
Integer('5') #=> 5
如果您希望在无法将字符串转换时返回nil,则仍需要使用number_or_nil方法。
def number_or_nil(string)
Integer(string || '')
rescue ArgumentError
nil
end
你应该小心地从特定的异常中进行救援。裸的救援(例如 "rescue nil")会救援任何继承自StandardError的错误,并可能以你意想不到的方式干扰程序的执行。Integer()将引发ArgumentError,因此请指定它。
如果您不想处理异常,只想使用更短的number_or_nil版本,可以利用隐式返回值,并将其写为:
def number_or_nil(string)
num = string.to_i
num if num.to_s == string
end
number_or_nil '5' #=> 5
number_or_nil '5abc' #=> nil
这将按您的期望工作。
Integer(nil)
会引发 TypeError
错误,因此使用 Integer(string || '')
更加一致。 - RocketRInteger('5', 10)
,它会明确使用十进制。否则,如果你输入像 Integer('08')
这样的内容,它会因为假设错误的进制而导致错误。请注意保持原意,同时使语言通俗易懂。 - LevseroInteger('0010') => 8
,所以不行——你不能只给出一个字符串,然后交叉你的手指,希望一切顺利,因为一个前导零这样简单的问题会让方法认为你正在处理二进制数字。 - bbozoexception
的关键字参数来完成此任务。> Integer('42', exception: false)
=> 42
> Integer('x42', exception: false)
=> nil
> Integer('x42')
ArgumentError (invalid value for Integer(): "x42")
> Integer('', exception: false)
=> nil
> Integer('')
ArgumentError (invalid value for Integer(): "")
> Integer(nil, exception: false)
=> nil
> Integer(' 42 ', exception: false)
=> 42
> Integer(' 4 2 ', exception: false)
=> nil
请注意,Integer还让您控制进制,这是to_i不支持的功能:to_i
。> '0xf'.to_i
=> 0
> Integer('0xf')
=> 15
> Integer('10', 8)
=> 8
当指定基数时,进制前缀(0x...
等)必须保持一致(如果存在):
> Integer('0xf', 10)
=> ArgumentError(invalid value for Integer(): "0xf")
> Integer('0xf', 16)
=> 15
> Integer('f', 16)
=> 15
str
是否为整数。def number_or_nil(str)
str.to_i if str[/^-?\d+$/] and str.line.size == 1
end
' 5 '
应该是5
还是nil
? - Uri Agassito_i
有什么问题?什么是“这种转换”? - sawa'5.0'
或者'5.1'
呢?它们肯定是打算作为数字使用的,既然你这样提问,它们不也应该被转换为整数吗? - Daniël Knippers[1,2,'cat'].reduce { |t,e| t + e.to_i } #=> 3
。同样也是真实的,nil.to_i #=> 0
,这可能很方便:a = [1,2,3].map { |e| e**2 if e < 3 } #=> [1, 4, nil]; a.reduce { |t,e| t + e.to_i } #=> 5
。 - Cary Swoveland