新手问题 麻烦问下大家关于 ruby 的 throw 和 catch 的问题

slidoooor-github · 2016年11月24日 · 最后由 wjnzxn 回复于 2019年08月02日 · 2232 次阅读

小弟刚刚开始学 ruby,对 ruby 的错误处理有点疑惑,,下边是代码,

def promptAndGet(prompt)
   print prompt
   res = readline.chomp
   throw :quitRequested if res == "!"
   return res
end

catch :quitRequested do
   name = promptAndGet("Name: ")
   age = promptAndGet("Age: ")
   sex = promptAndGet("Sex: ")
   # ..
   # 处理信息
end
promptAndGet("Name:")

我的想法是 这里如果我输入的等于感叹号他才会跳到错误处理,如果不是感叹号的话就会直接返回,但是好像并不是,我输入非感叹号字符之后他会直接让我输入 age,也就是走到了错误处理的第二个方法,,而且我想的是我输入之后他进入到错误处理再次调用这个方法,应该会形成一个循环,,但是并没有,所以这里有点疑惑,还有就是第一次输入感叹号是会跳到异常处理的,但是在异常处理这个方法输入感叹号就会报错,这里我也不太明白,因为有些绕,所以感觉自己也表达不太清楚,,麻烦大家了..

ruby 里面异常处理的普通来说是 raise / rescue
要进行继续处理而言用 yield/Fiber.yield 甚至 callcc
而 catch/throw 的作用并不像在其它语言里面一样是异常处理,更多的是流程控制。
比如快速跳出多重方法/catch 块,throw 的作用是跳到同名 catch 块的后续,catch 块可以有返回值,一般是最后一条表达式的值,发生 throw 时,如果 throw 带了第二个参数那么以这个参数作为值
比如

a = catch :foo do
  catch :bar do
     throw :foo, 3
  end
end

则 throw 直接让 catch :foo 返回且之后 a = 3

因为你的理解有问题,catch throw 原理是:程序开始会从 catch 的程序块往下走,catch 会带一个标签(你例子中标签是 quitRequested)当遇到带有同名标签的 throw 的时候就会跳出 catch 代码块,如果 throw 后面带条件,同时还要满足条件才跳出,否则不跳出,将会继续执行 catch 代码块的全部代码。

因此如果你一直不输入“!”的条件下 程序会让你输入 3 次 , 跳出 catch 后还会让你输入一次,结果如下

Name:空格 + 你的输入 Age:空格 + 你的输入 Sex:空格 + 你的输入 Name:你的输入

如果你第 1 次就输入“!”

Name:空格! Name:你的输入

如果你第 2 次才输入“!”

Name:空格 + 你的输入 Age:空格! Name:你的输入

需要 登录 后方可回复, 如果你还没有账号请 注册新账号