Ruby 分配一个变量或在 nil 时引发错误

如何解决Ruby 分配一个变量或在 nil 时引发错误

在 kotlin 和 C# 中,您可以分配一个变量,否则如果值为 nil,您可以使用 ?:?? 运算符抛出异常。

例如,在 C# 中:

var targetUrl = GetA() ?? throw new Exception("Missing A");
// alt
var targetUrl = GetA() ?? GetB() ?? throw new Exception("Missing A or B");

这在 ruby​​ 中可行吗?如果是这样,如何?

基本上,我想做的是这个

target_url = @maybe_a || @maybe_b || raise "either a or b must be assigned"

我知道我可以做到这一点

target_url = @maybe_a || @maybe_b
raise "either a or b must be assigned" unless target_url

但如果可能的话,我想在一行中完成

解决方法

基本上,我想做的是这个

target_url = @maybe_a || @maybe_b || raise "either a or b must be assigned"

您必须为 raise 添加括号才能使您的代码正常工作:

x = a || b || raise("either a or b must be assigned")

使用控制流运算符 or 而不是 || 会“更正确”:(这使得括号可选)

x = a || b or raise "either a or b must be assigned"

这是 Perl 的“do this or die” 成语,我认为它干净整洁。它强调了一个事实,即 raise 不为 x 提供结果 - 它只是因其副作用而被调用。

然而,有些人认为 or / and 令人困惑,根本不应该使用。 (见rubystyle.guide/#no-and-or-or

Rails 大量使用的一种模式是有两种方法,一种没有 !,它不提供错误处理:

def a_or_b
  @maybe_a || @maybe_b
end

和一个带有 ! 的函数:

def a_or_b!
  a_or_b || raise("either a or b must be assigned")
end

然后通过以下方式调用它:

target_url = a_or_b!
,

你可以用括号解决它:

(target_url = @maybe_a || @maybe_b) || raise("either a or b must be assigned")
,

使用运算符优先级

另一种以极少的代码更改完成您想要的操作的方法是使用 lower-precedence or 运算符,它的优先级低于 ||= .例如:

# This is closest to what you want,but violates many style guides.
target_url = @maybe_a || @maybe_b or raise "either a or b must be assigned"

您还可以在不改变其工作方式的情况下包装逻辑行,例如:

# Same code as above,but wrapped for line length
# and to clarify & separate its expressions.
target_url = @maybe_a || @maybe_b or
  raise "either a or b must be assigned"

无论哪种方式,代码都会按预期引发 RuntimeError 异常。由于优先规则,不需要括号。

请注意,许多 style guides like this one 会告诉您完全避免使用 or 运算符,或者仅将其用于流量控制,因为它通常是导致细微优先级错误的原因一目了然。话虽如此,包装版本实际上只是 my other answer 的倒置变体,并且在不使用括号的情况下很容易在视觉上区分,尤其是启用了语法突出显示。您的里程和风格指南的严格程度肯定会有所不同。

,

在赋值表达式中使用后缀条件

因为 Ruby 中的大部分内容都计算为一个表达式,您可以通过使用 unless 作为后缀条件后跟一个赋值表达式来将其作为单个逻辑行执行。我选择将线包裹起来以适应合理的线长,但如果您真的想要“单线”,请随意将其设为单线。例如:

raise "either a or b must be assigned" unless
  target_url = @maybe_a || @maybe_b

如您所料,这将正确引发 RuntimeError。

自动激活

请注意,这种特殊方法会自动激活 @maybe_a 并为其分配 nil。如果 @maybe_a 评估为 false,它也会对 @maybe_b 做同样的事情。虽然很方便,但如果您依赖 defined? 来识别代码中其他地方的未定义变量,自动激活可能会在以后绊倒您。因此,这个习语的优缺点取决于你更广泛的意图,但它肯定会在原始问题的范围内完成工作。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?