严格将字符串转换为整数(或零)

Ali*_*urn 50 ruby type-conversion

对于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
Run Code Online (Sandbox Code Playgroud)

有没有更整洁,更自然的方式来实现这种转换,并检测到字符串不是一个数字?

Jim*_*Gay 85

使用整数(字符串)

如果字符串无法转换为整数,则会引发ArgumentError错误.

Integer('5abc') #=> ArgumentError: invalid value for Integer(): "5abc"
Integer('5') #=> 5
Run Code Online (Sandbox Code Playgroud)

如果您希望行为为无法转换字符串时返回nil,则仍需要number_or_nil方法.

def number_or_nil(string)
  Integer(string || '')
rescue ArgumentError
  nil
end
Run Code Online (Sandbox Code Playgroud)

你应该小心拯救一个特殊的例外.裸露的救援(例如"救援无")将挽救任何继承自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
Run Code Online (Sandbox Code Playgroud)

这将以您期望的方式工作.

  • 唯一需要注意的是`Integer(nil)`引发`TypeError`,所以`Integer(string ||'')`更加一致. (3认同)
  • 我在哪里可以找到“整数(字符串)”的(官方)文档?据我所知,官方 [ruby `Integer` 文档](http://ruby-doc.org/core-2.2.3/Integer.html) 中没有提到它。 (3认同)
  • 现在来了脑筋*时间:`整数('0010')=> 8`所以没有 - 你不能只是给它一个字符串并交叉你的手指希望最好,因为像前导零一样简单的东西会使假设您正在处理二进制数 (3认同)
  • 你可能想要指定基数10`Integger('5',10)`,否则如果你得到类似`Integer('08')的东西,它会因为假定错误的基数而引发错误. (2认同)

aki*_*kim 13

至少从 Ruby 2.6 开始,内核函数 Integer、Float 等接受一个exception关键字参数来完成这项工作:

> 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
Run Code Online (Sandbox Code Playgroud)