首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么这个例外没有被救援队抓住?

为什么这个例外没有被救援队抓住?
EN

Stack Overflow用户
提问于 2018-09-19 17:49:17
回答 1查看 535关注 0票数 2

我运行了这个代码:

代码语言:javascript
复制
begin
  print 'Enter something:'
  x = gets.to_i          # Enter a string
rescue => err
  print(err.to_s)
end

我不明白为什么救援队没有抓住例外。当输入字符串时,它总是返回零,并且不触发救援块。我不知道为什么不管用。有人能帮忙吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-09-19 21:52:28

String#to_i和Kernel#Integer的行为不同

您的异常处理程序从未被调用的原因是不引发异常,即使它无法检测到字符串对象中的有效整数。在这种情况下,它只返回0

相比之下,Kernel#Integer的行为更为复杂,但如果字符串的内容不严格符合数字表示形式,则会引发ArgumentError或TypeError。

因此,要最小化地重构现有代码以引发对非数字输入的异常:

代码语言:javascript
复制
begin
  print 'Enter something: ' 
  x = Integer gets
rescue => err
  # Do something other than just print err on STDERR, which is the 
  # default behavior anyway. Perhaps send it to STDOUT instead.
  puts "I received an exception: #{err}"

  # After handling, re-raise the original exception with or without
  # passing the original exception object. `raise` and `raise err` 
  # will do the same thing here.
  raise

  # For more advanced uses, you can also do something else like raise 
  # a different exception (e.g. TypeError), or modify the exception
  # object stored in err and raise that modified object instead.
end

以下用户输入将清晰地转换:

  • 1
  • 2
  • 0xff

在大多数情况下,代码甚至将处理初始/尾随空格、换行符和回车,而不需要您做任何额外的努力。然而:

  • 输入:一 ArgumentError: Integer()的无效值:"one\n“
  • 输入:"1“ ArgumentError: Integer()的无效值:"\"1\"\n“
  • 输入:零 ArgumentError: Integer()的无效值:"nil\n“

通常,您可以依赖Kernel#Integer在必要时引发异常,这大大简化了代码。不过,请参阅下面的警告。

注意事项

这些示例不需要它,但您也可能希望在必要时使用#条带、#chomp或其他字符串转换来清理您的输入。在这方面,您的里程将因实际用例而有很大差异,但是虽然Kernel#Integer通常会做正确的事情,而且Ruby鼓励依赖异常来处理非标准的边缘情况,但信任受用户污染的输入通常是不明智的。

还值得注意的是,String#to_i和Kernel#Integer都可能对用户输入以外的值进行操作,在这种情况下,Integer(nil)将引发:

整数零 TypeError:无法将零转换为整数

这可能很重要。再一次,你的里程可能会有所不同。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52411577

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档