哪种代码更具可读性?
假设我有两个方法 bool Foo()
和 bool Bar()
。以下哪一个更具可读性?
if(Foo())
{
SomeProperty = Bar();
}
else
{
SomeProperty = false;
}
或
SomeProperty = Foo() && Bar();
一方面,我认为短路 &&
是一个有用的功能,并且第二个代码示例要短得多。另一方面,我不确定人们通常是否习惯在条件语句之外看到 &&
,所以我想知道这是否会引入一些认知失调,从而使第一个样本成为更好的选择。
你怎么认为?还有其他因素影响决策吗?例如,如果 &&
表达式比屏幕上可以容纳的一行长,我应该选择前者吗?
回答后澄清:
我应该在答案提出的最初问题中包含一些内容。
Bar()
的执行成本可能比Foo()
更高,但这两种方法都不应该有副作用。- 这两个方法的命名都更合适,而不是像本例中那样。
Foo()
可以归结为CurrentUserAllowedToDoX()
之类的东西,而Bar()
则更像是XCanBeDone()
Suppose I have two methods bool Foo()
and bool Bar()
. Which of the following is more readable?
if(Foo())
{
SomeProperty = Bar();
}
else
{
SomeProperty = false;
}
or
SomeProperty = Foo() && Bar();
On the one hand, I consider the short-circuiting &&
to be a useful feature and the second code sample is much shorter. On the other hand, I'm not sure people are generally accustomed to seeing &&
outside a conditional statement, so I wonder if that would introduce some cognitive dissonance that makes the first sample the better option.
What do you think? Are there other factors that affect the decision? Like, if the &&
expression is longer than one line that can fit on the screen, should I prefer the former?
Post-answer clarifications:
A few things that I should have included in the initial question that the answers brought up.
Bar()
may be more expensive to execute thanFoo()
, but neither method should have side effects.- The methods are both named more appropriately, not like in this example.
Foo()
boils down to something likeCurrentUserAllowedToDoX()
andBar()
is more like,XCanBeDone()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(21)
当我阅读第一个时,直到您阅读语句的 else 部分之前,并没有立即明显看出 SomeProperty 是一个布尔属性,也不是 Bar() 返回布尔值。
我个人的观点是,这种方法应该是最佳实践:每一行代码都应该尽可能地可解释,并且引用尽可能少的其他代码。
因为语句一要求我引用语句的 else 部分来插入 SomeProperty 和 Bar() 本质上都是布尔值,所以我将使用第二个。
在第二个例子中,通过一行代码可以立即明显看出以下所有事实:
When I read the first one, it wasn't immediately obvious SomeProperty was a boolean property, nor that Bar() returned a boolean value until you read the else part of the statement.
My personal view is that this approach should be a best practice: Every line of code should be as interpretable as it can with reference to as little other code as possible.
Because statement one requires me to reference the else part of the statement to interpolate that both SomeProperty and Bar() are boolean in nature, I would use the second.
In the second, it is immediately obvious in a single line of code all of the following facts:
第一个,它更容易调试
The first one, it's much more debuggable
我认为,最好的方法是使用 SomeProperty = Foo() && Bar(),因为它要短得多。我认为任何普通的 .NET 程序员都应该知道 && 运算符是如何工作的。
I think, that best way is use
SomeProperty = Foo() && Bar()
, because it is much shorter. I think that any normal .NET-programmer should know how &&-operator works.我会选择长版本,因为乍一看就很清楚它的作用。在第二个版本中,您必须停下来几秒钟,直到您意识到 && 的短路行为。操作员。这是聪明的代码,但不是可读的代码。
I would choose the long version because it is clear at first glance what it does. In the second version, you have to stop for a few secons until you realize the short-circuit behavior of the && operator. It is clever code, but not readable code.
等一下。这些陈述甚至不等同,不是吗?我已经看过它们好几次了,但它们的评价并不相同。
第一个版本的简写将使用三元运算符,而不是“and”运算符。
然而,除了逻辑错误之外,我同意其他人的观点,即较短的版本更具可读性。
编辑 - 添加
再说一遍,如果我错了并且没有逻辑错误,那么第二个代码的可读性更高,因为代码的作用非常明显。
再次编辑 - 添加更多:
现在我看到了。没有逻辑错误。然而,我认为这表明较长的版本对于我们这些还没有喝过咖啡的人来说更清楚。
Wait a minute. These statements aren't even equivalent, are they? I've looked at them several times and they don't evaluate to the same thing.
The shorthand for the first version would be using the ternary operator, not the "and" operator.
However, logic error aside, I agree with everyone else that the shorter version is more readable.
Edit - Added
Then again, if I'm wrong and there IS no logic error, then the second is way more readable because it's very obvious what the code is doing.
Edit again - added more:
Now I see it. There's no logic error. However, I think this makes the point that the longer version is clearer for those of us who haven't had our coffee yet.
如果,正如您所指出的, Bar() 有副作用,我会更喜欢更明确的方式。否则,有些人可能不会意识到您打算利用短路。
如果 Bar() 是独立的,那么我会采用更简洁的方式来表达代码。
If, as you indicate, Bar() has side effects, I would prefer the more explicit way. Otherwise some people might not realize that you are intending to take advantage of short circuiting.
If Bar() is self contained then I would go for the more succinct way of expressing the code.
如果第一个版本看起来像这样:
或像这样:
那么它至少会一致。这样一来,逻辑就比第二种情况更难遵循。
If the first version looked like this:
or like this:
Then it would at least be consistent. This way the logic is much harder to follow than the second case.
能够单独对任何特定函数调用以及将变量设置为特定值的任何特定断点通常很有用——因此,也许有争议的是,我倾向于选择第一个选项。这更有可能允许在所有调试器中设置细粒度的断点(对于 C# 来说,断点的数量不是很大)。
这样,可以在调用 Foo() 之前、调用 Bar() (以及变量集)之前以及当变量设置为 false 时设置断点——显然,也可以设置相同的断点用于捕获 Foo() 与 !Foo() 情况,具体取决于人们想到的问题。
当一切都在一条线上时,这并非不可能做到,但它需要注意,可以用来找出正在调查的任何问题的原因。
(C# 编译速度很快,因此重新排列代码通常不是一个大问题,但会分散注意力。)
It is often useful to be able to breakpoint any specific function call individually, and also any specific setting of a variable to a particular value -- so, perhaps controversially, I would be inclined to go for the first option. This stands a greater chance of allowing fine-grained breakpointing across all debuggers (which in the case of C# is not a very large number).
That way, a breakpoint may be set before the call to Foo(), before the call to Bar() (and the set of the variable), and when the variable is set to false -- and obviously the same breakpoints could also be used to trap the Foo() vs !Foo() cases, depending on the question one has in mind.
This is not impossible to do when it is all on one line, but it takes attention that could be used to work out the cause of whatever problem is being investigated.
(C# compiles quickly, so it is usually not a big problem to rearrange the code, but it is a distraction.)
在我看来,这归根结底是有意且清晰的。
第一种方法让不经意的观察者清楚地知道,除非 Foo() 返回 true,否则您不会执行 Bar()。我知道短路逻辑将阻止 Bar() 在第二个示例中被调用(我自己可能会这样写),但第一种方法乍一看更加有意。
It comes down to being intentional and clear, in my mind.
The first way makes it clear to the casual observer that you aren't executing Bar() unless Foo() returns true. I get that the short circuit logic will keep Bar() from being called in the second example (and I might write it that way myself) but the first way is far more intentional at first glance.
AND 行为的短路并不是所有语言中的标准,因此如果这对我的代码至关重要的话,我倾向于谨慎使用它。
我不相信自己在一天中第五次切换语言后会立即看到短路。
因此,如果当 Foo() 返回 false 时永远不应该调用 Boo(),那么我会使用版本 #2,哪怕只是作为一种防御性编程技术。
Short-circuiting of AND behavior is not standard in all languages, so I tend to be wary of using it implicitly if that's essential to my code.
I don't trust myself to see the short-circuit immediately after I've switched languages for the fifth time in the day.
So if Boo() should never be called when Foo() returns false, I'd go with version #2, if only as a defensive programming technique.
第一种方法可读性更强,但代码行数更多,第二种方法更有效,没有比较,只有一行!我认为第二个更好
First method is more readable, but get more lines of codes, second is more EFFECTIVE, no comparision, only one line! I think that second is better
由于您使用的是 c#,我会选择第一个版本或使用三元
?:
运算符。以这种方式使用&&
在 C# 中并不常见,因此您更有可能被误解。在其他一些语言(我想到的是 Ruby)中,&&
模式更流行,我想说它在这种情况下是合适的。Since you're using c#, I would choose the first version or use the ternary
?:
operator. Using&&
in that manner isn't a common idiom in c#, so you're more likely to be misunderstood. In some other languages (Ruby comes to mind) the&&
pattern is more popular, and I would say it's appropriate in that context.我想说,如果代码对于不了解实际编程语言的人来说是可读的,那么这样的代码
更具可读性,那么它将花费更多的时间
比如果程序员在你不熟悉后一种语法后接管代码 他的时间是你写那些额外的几个字符所花费的时间的十倍。
I would say code is readable if it is readable to a person with no knowledge of the actual programming language so therefore code like
is much more readable than
If the programmer taking over the code after you isn't familiar with the latter syntax it will cost him 10 times the time it takes you to write those extra few characters.
我同意 Foo() && 的普遍共识。 Bar() 形式是合理的除非 Bar() 因其副作用及其价值而有用。
如果 Bar() 因其副作用而有用,则为:除了它的价值之外,我的第一选择是重新设计 Bar() ,以便其副作用的产生和其值的计算是单独的方法。
如果由于某种原因这是不可能的,那么我会非常喜欢原始版本。对我来说,原始版本更清楚地强调对 Bar() 的调用是对其副作用有用的语句的一部分。对我来说,后一种形式强调了 Bar() 的价值。
例如,如果在
和
之间进行选择,我会选择前者;对我来说,很容易忽视后者的重要副作用。
不过,如果要在
和
之间做出选择的话,我会选择后者。
I agree with the general consensus that the Foo() && Bar() form is reasonable unless it is the case that Bar() is useful for its side effects as well as its value.
If it is the case that Bar() is useful for its side effects as well as it's value, my first choice would be to redesign Bar() so that production of its side effects and computation of its value were separate methods.
If for some reason that was impossible, then I would greatly prefer the original version. To me the original version more clearly emphasizes that the call to Bar() is part of a statement that is useful for its side effects. The latter form to me emphasizes that Bar() is useful for its value.
For example, given the choice between
and
I would take the former; to me, it is too easy to overlook the important side effect in the latter.
However, if it were a choice between
and
I'd choose the latter.
假设您的语言允许,我喜欢这种简写符号:
I like this shorthand notation assuming your language permits it:
这更具可读性。我不明白怎么会有人坦白地选择另一个。如果 &&表达式比 1 行长,将其分成 2 行...
恕我直言,这几乎不影响可读性和理解。
This is way more readable. I don't see how anyone could choose the other one frankly. If the && expression is longer then 1 line, split it into 2 lines...
That barely hurts readability and understanding IMHO.
这取决于 Foo 和 Bar 做什么。
例如,IsUserLoggedIn() && IsUserAdmin() 作为
&&
肯定会更好,但是还有一些其他组合(我想不出任何临时的),其中 if 会更好。总的来说,我会推荐
&&
。It depends on what Foo and Bar do.
For example,
IsUserLoggedIn() && IsUserAdmin()
would definitely be better as an&&
, but there are some other combinations (I can't think of any offhand) where the ifs would be better.Overall, I would recommend
&&
.两者都不。我首先重命名 SomeProperty、Foo 和 Bar。
我的意思是,您应该构建代码以清楚地传达您的意图。对于不同的功能,我可能会使用不同的形式。然而,就目前情况而言,任何一种形式都可以。考虑:
and
在这里,第一种形式强调逻辑与关系。第二个强调短路。我永远不会用第二种形式写第一个例子。对于第二个示例,我可能更喜欢第二种形式,特别是如果我的目标是清晰的话。
重点是,用 SomeProperty 和 Foo() 和 Bar() 很难回答这个问题。有一些很好的、通用的答案来捍卫 &&对于通常情况,但我永远不会完全排除第二种形式。
Neither. I'd start with renaming SomeProperty, Foo and Bar.
What I mean is, you should structure your code as to convey your intentions clearly. With different functions, I might use different forms. As it stands, however, either form is fine. Consider:
and
Here, the first form stresses the logical-and relationship. The second one stresses the short-circuit. I would never write the first example in the second form. I would probably prefer the second form for the second example, especially if I was aiming for clarity.
Point is, it's hard to answer this question with SomeProperty and Foo() and Bar(). There are some good, generic answers defending && for the usual cases, but I would never completely rule out the second form.
您认为人们可能会以何种方式误解第二个?你认为他们会忘记吗&&短路,并担心如果第一个条件为 false 时调用第二个条件会发生什么?如果是这样,我就不会担心这一点 - 他们也会同样感到困惑:
我认为很多人不会将其重写为第一种形式。
基本上,我会选择第二个。有了适当的描述性变量名称(和条件),它应该绝对没问题。
In what way do you think people might misinterpret the second one? Do you think they'll forget that && shortcircuits, and worry about what will happen if the second condition is called when the first is false? If so, I wouldn't worry about that - they'd be equally confused by:
which I don't think many people would rewrite as the first form.
Basically, I'd go with the second. With a suitably descriptive variable name (and conditions) it should be absolutely fine.
在条件表达式简短且简洁的情况下(就像本例一样),我发现第二个更具可读性。一目了然你想在这里做什么。第一个例子花了我两遍才明白发生了什么。
In the case where the conditional expressions are short and succinct, as is this case, I find the second to be much more readable. It's very clear at a glance what you are trying to do here. The first example though took me 2 passes to understand what was happening.
我会选择第二次,但可能会像第一次一样写,然后我会改变它:)
I would go for the second, but would probably write it like the first time, and then I would change it :)