只要不损害可读性,简单的三元情况是不是可以在程序流中使用?

Posted

技术标签:

【中文标题】只要不损害可读性,简单的三元情况是不是可以在程序流中使用?【英文标题】:Is a simple ternary case okay for use in program flow as long as it does not hurt readability?只要不损害可读性,简单的三元情况是否可以在程序流中使用? 【发布时间】:2011-11-24 14:57:44 【问题描述】:

在阅读了To ternary or not to ternary? 和Is this a reasonable use of the ternary operator? 之后,我了解到三元运算符的简单用法是普遍接受的,因为它们不会损害可读性。我还收集到当你不希望它做某事时让三元块的一侧返回 null 是完全浪费的。但是,我在重构我的网站时遇到了这种情况,这让我皱起了鼻子:

if ($success) 
    $database->commit();
 else 
    $database->rollback();

我把它重构为

$success ? $database->commit() : $database->rollback();

我对此非常满意.. 但我内心的某些东西让我来到这里寻求意见。抛开异常,你认为这是一个好的用例吗?我想知道这是否可以使用,因为我以前从未这样做过,还是因为这真的是不好的做法?这对我来说似乎并不难,但对于其他人来说,这似乎很难理解吗?它是否取决于语言.. 就像在 C、C++ 或 Java 中这会或多或少是错误的吗?

【问题讨论】:

考虑三元表达式要求两个函数有返回值,即使调用代码忽略它们。如果函数后来被修改为不返回值,比如因为返回值在任何地方都被忽略,那么你的三元表达式需要修改——以适应它已经忽略的返回值的缺失。 'if' 语句更能适应变化。 【参考方案1】:

不,不行。您正在将看起来像语句的东西变成看起来像表达式的东西。事实上,如果commit()rollback() 返回void,至少在Java 中不会编译(不确定其他提到的)。

如果您想要一个单行,您应该在 $database 对象上创建另一个方法,例如在内部执行 if 语句的 $database->endTransaction($success)

【讨论】:

如果commit()rollback() 方法返回类型是void 或没有通用超类型,我很确定它不会在Java 中编译。至于为什么让语句看起来像表达式是错误的,那就更微妙了。表达通常不应该有副作用 - 它只是不是人们所期望的,它使控制流不清楚。 我非常喜欢这个答案,因为它从我的特定服务调用中删除了重复的三元代码并将其推送到一个集中位置。我肯定会实施这一点,谢谢:) 我误解了你说的第一件事,但我现在明白你的意思了。我没有意识到 Java 的这一点。 想了想,我可能仍然不会在内部执行 if 语句,但我会继续在该函数中使用三元运算符,就像这样: return $success ? $this->commit() : $this->rollback();这一切都是为了在保护清晰的同时拥抱简洁。 “表达通常不应该有副作用——它只是不是人们所期望的”——这与语言无关。一个可能的领头羊:如果你的语言有++-- 运算符,那么表达式预计会有副作用,或者至少它们是由那些甚至有模糊现实期望的人产生的。如果该语言没有这些运算符或等价物,那么通过省略它们,它会在某种意义上反对表达式中的副作用,所以也许值得在这种约束下进行编程。 @abelito:例如,Python 没有++--。 Python 中没有严格的规定,表达式不能有副作用,它们可以而且有时会。但作为一种风格,Python 库倾向于定义变异函数返回 None,只是为了促使用户编写任何带有副作用的东西作为独立语句。经典的例子是mylist.sort() 修改了列表,并且不返回任何内容,因此不太可能将其用作更大语句的一部分。 sorted(mylist) 返回:列表的副本,原始未修改。这是一种有用的风格。【参考方案2】:

如果两个动作相互排斥和/或相反(但彼此相关),我会更倾向于使用它,例如:

$success ? go_up() : go_down();

对于两个不相关的操作,我不太愿意使用它,原因是其中一个分支将来需要扩展的可能性更高。如果是这种情况,您将再次需要将其重写为 if-else 语句。想象一下,你有:

$success ? do_abc() : do_xyz();

如果在某个时候您决定第一个分支也需要 do_def(),则需要将整个内容重新重写为 if-else 语句。

然而,三元运算符更常见的用法是:

$var = $success ? UP : DOWN;

这样,您将其作为表达式而不是语句进行评估。

【讨论】:

是的,这种用法肯定有一个小众市场,我完全同意最终需要扩展。我只是想到了提交本身由于某种原因而失败的情况,我需要捕获它并将其显示在用户的屏幕上。嗯,突然间我也需要跟踪成功并返回它。 我喜欢你的使用指南。 Ramon 通过建议将这个逻辑从服务调用中推到服务本身中以进行重用,为我正在做的事情提供了一个非常好的替代方案。但是,我认为您的答案的前半部分解释了以这种方式使用三元运算符的一些可靠准则。我仍然不相信语言中没有这种用途。【参考方案3】:

真正的问题是,“三元形式是否比 if 形式更具可读性?”。我会说不是。但这是风格问题,而不是功能问题。

【讨论】:

以上是关于只要不损害可读性,简单的三元情况是不是可以在程序流中使用?的主要内容,如果未能解决你的问题,请参考以下文章

网络流最大流

php 中 三元运算和 IF语句 运行速度

python程序的编写简单介绍

python程序的编写简单介绍

python- python程序的编写简单介绍

如何在不损害可访问性的情况下删除 Firefox 链接中的虚线轮廓?