除了短路之外,在 'if' 语句中是否有理由更喜欢 '&&' 而不是 '&'?

Is there a reason to prefer '&&' over '&' in 'if' statements, other than short-circuiting?

是的,我知道,有很多关于 &&& 在 R 中的用法的问题(例如,参见 this one),但我没有找到了专门回答我问题的。

根据我的理解,

此外,if 发出警告

the condition has length > 1 and only the first element will be used

如果它的条件有一个以上的元素。

从这些初步判断来看,我认为在不需要短路的所有 if 语句中更喜欢 &&& 更安全.

如果在计算过程中出现问题并且我不小心在 & 的参数之一中包含了一个向量,我会收到警告,这很好。如果没有,一切都很好。

另一方面,如果我使用了 &&,并且在我的计算中出现了错误并且 && 的参数之一是向量,我不会收到警告。这是不好的。如果出于某种原因,我真的想比较两个向量的第一个元素,我认为显式比隐式比较更清晰。

请注意,这似乎违背了 R 程序员之间的共识,也违背了 R 文档的推荐。 (1)

因此我的问题:在if语句中,除了短路之外,是否还有其他原因使&&优于&


(1) 引用 help(&&):

'&' and '&&' indicate logical AND and '|' and '||' indicate logical OR. The shorter form performs elementwise comparisons in much the same way as arithmetic operators. The longer form evaluates left to right examining only the first element of each vector. Evaluation proceeds only until the result is determined. The longer form is appropriate for programming control-flow and typically preferred in 'if' clauses.

,使用&&除了短路之外没有任何优势。

但是,短路对于控制流来说非常可取,以至于它应该是默认设置。 if 语句不应采用矢量化参数 - 这就是 ifelse 的用途。如果您将逻辑向量传递给 if,通常您会使用 anyall 将其收缩为单个逻辑值以进行评估。

短路的主要优点是避免冗长或容易出错的步骤(例如互联网连接 - 虽然这些应该通过 try 处理):

#avoiding lengthy calculations
system.time(if(FALSE & {Sys.sleep(2);TRUE}) print("Hello"))
   user  system elapsed 
   0.00    0.00    1.99 
system.time(if(FALSE && {Sys.sleep(2);TRUE}) print("Hello"))
   user  system elapsed 
      0       0       0 

#avoiding errors
if(FALSE & {stop("Connection Failed");TRUE}) print("Success") else print("Condition not met")
Error: Connection Failed
if(FALSE && {stop("Connection Failed");TRUE}) print("Success") else print("Condition not met")
[1] "Condition not met"

很明显,为了利用这些功能,您必须事先知道哪些步骤花费的时间最长或容易出错,并适当地构建逻辑语句。

简短回答:是的,不同的符号使reader的意思更清楚。

感谢您提出这个有趣的问题!如果我可以总结一下,这似乎是关于 my answer 中您链接的问题的这一部分的后续行动,

... you want to use the long forms only when you are certain the vectors are length one. You should be absolutely certain your vectors are only length 1, such as in cases where they are functions that return only length 1 booleans. You want to use the short forms if the vectors are length possibly >1. So if you're not absolutely sure, you should either check first, or use the short form and then use all and any to reduce it to length one for use in control flow statements, like if.

我是这样听到你的问题(给出评论)的:但是如果输入的长度是 1,&&& 会做同样的事情,所以除了短 -循环,为什么更喜欢&&?也许 & 应该是首选,因为如果它们的长度不是一,if 会给我一个 warning,帮助我更加确定输入的长度是一。

首先,我同意@James 的评论,您可能是"overstating the value of getting a warning";如果不长,妥善处理比较稳妥,而不是硬着头皮往前走。你可以假设 && 如果长度不是 1 就应该抛出一个错误,这也许是一个很好的案例;我不知道它为什么这样做的原因。但是,如果不能回到过去,我们现在能做的最好的事情就是检查输入是否确实适合您的使用。

鉴于您已经检查过以确保您的输入是合适的,我仍然会推荐 && 因为它在语义上提醒我作为 reader 我应该确保输入是正确的标量(长度为一)。我已经习惯了向量化思考,这个提醒对我很有帮助。它遵循的原则是不同的操作应该有不同的符号,对我来说,用于标量的操作与矢量化操作完全不同,它 war 需要不同的符号。

(不是为了煽风点火war(我希望如此),但这也是为什么我更喜欢<-而不是=的原因;一种用于分配变量,一种用于设置参数功能。虽然在本质上这是同一件事,但在实践中它的差异足以使不同的符号对我有用 reader。)