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

时间:2015-04-27 14:42:22

标签: r vectorization conventions

是的,我知道,有关R中&&&的使用情况的问题(例如,请参阅this one),但我没有找到一个问题这特别回答了我的问题。

据我了解差异,

  • &进行逐元素的矢量化比较,就像其他算术运算一样。因此,它返回长度> 1的逻辑矢量。如果两个参数都具有长度> 1,则为1; 1。
  • &&比较两个向量的第一个元素,并始终返回长度为1的结果。此外,它短路cond1 && cond2 && cond3 && ...仅评估{{1}如果cond2cond1,等等。这允许TRUE之类的内容,特别是在某些情况下使用if(exists("is.R") && is.function(is.R) && is.R())是绝对必要的。

此外,&&发出警告

  

条件的长度> 1,只使用第一个元素

如果其条件有多个元素。

从这些预赛判断来看,我认为在不需要短路的所有if声明中更倾向于&&&更安全。

如果在计算过程中出现问题,我意外地在if的一个参数中有一个向量,我会收到警告,这很好。如果没有,一切都很好。

另一方面,如果我使用&,并且在我的计算中出现了问题,并且&&的一个参数是向量,我不会收到警告。这是不好的。如果出于某种原因,我真的想比较两个向量的第一个元素,我认为明确而不是隐含地这样做会更清晰。

请注意,这与R程序员之间的共同协议相反,与R docs推荐的内容相反。 (1)

因此我的问题:除了短路之外是否有任何理由使&&优于&& &语句中的if

(1)引用help(&&)

  

'&安培;'和'&&'表示逻辑AND和'|'和'||'表明   逻辑或。较短的形式执行元素比较   与算术运算符的方式大致相同。更长的形式   从左到右评估只检查每个元素的第一个元素   向量。评估仅在确定结果之前进行。   较长的形式适用于编程控制流程和   通常在'if'子句中首选。

2 个答案:

答案 0 :(得分:5)

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

然而,对于控制流程来说,短路是非常可取的,因此它应该是默认值。 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"

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

答案 1 :(得分:5)

简答:是的,不同的符号使读者的意思更加明确。

感谢这个有趣的问题!如果我可以总结一下,对于您所关联的问题,my answer的这一部分似乎是一个具体的后续行动,

  

...只有在确定时,才想使用长格式   向量是长度一。你应该绝对肯定你的向量   只有长度为1,例如在它们是函数的情况下   只返回长度为1的布尔值。你想要使用短格式   向量的长度可能> 1。所以,如果你不完全确定,那么你   应首先检查,或使用简短形式,然后使用全部和   任何将它减少到长度1用于控制流程语句,   喜欢如果。

我以这种方式听到你的问题(给出评论):但如果输入是长度为1,&&&会做同样的事情,所以除了短路之外,为什么更喜欢&&?也许&可能是首选,因为如果它们不是长度为1,if会给我一个警告,帮助我更加确定输入是长度为一。

首先,我同意@James的评论,你可能会夸大警告的价值&#34 ;;如果它不是长度1,那么更安全的事情就是妥善处理这个问题,而不仅仅是向前耕作。如果&&不是一个长度,那么你可以提出&&应该抛出错误的情况,也许是一个好例子;我不知道它为什么会这样做。但是,如果不及时回过头来,我们现在能做的最好的事情就是检查输入确实适合您的使用。

鉴于此,您已经检查以确保您的输入是合适的,我仍然会建议<-因为它在语义上提醒我作为读者我应该确保输入是标量(长度为1)。我过去常常想到这个提醒对我有帮助。它遵循以下原则:不同的操作应该有不同的符号,对我来说,一个用于标量的操作与矢量化操作不同,它保证了一个不同的符号。

(不要开始一场火焰战(我希望),但这也是我更喜欢=var yourWindow = window.open('http://google.com'); 的原因;一个用于分配变量,一个用于将参数设置为函数。虽然这很深同样的事情,它在实践中的不同之处在于使不同的符号对我作为读者有用。)