292

根据R语言的定义&,和&&(对应的|和)的区别在于||前者是向量化的,而后者不是。

根据帮助文本,我读到了类似于“And”和“AndAlso”(相应地“Or”和“OrElse”)之间的区别......意思是:如果不是所有的评估都必须是(即如果 A 为真,则 A 或 B 或 C 始终为真,因此停止评估 A 是否为真)

有人可以在这里阐明吗?此外,R 中是否有 AndAlso 和 OrElse?

4

3 回答 3

395

较短的被向量化,这意味着它们可以返回一个向量,如下所示:

((-2:2) >= 0) & ((-2:2) <= 0)
# [1] FALSE FALSE  TRUE FALSE FALSE

较长的形式从左到右评估只检查每个向量的第一个元素,所以上面给出

((-2:2) >= 0) && ((-2:2) <= 0)
# [1] FALSE

正如帮助页面所说,这使得较长的形式“适用于编程控制流,并且通常在 if 子句中首选。”

因此,只有当您确定向量的长度为 1 时,您才想使用长格式。

您应该绝对确定您的向量的长度仅为 1,例如在它们是仅返回长度为 1 布尔值的函数的情况下。如果向量的长度可能 > 1,您想使用简短形式。因此,如果您不确定,您应该先检查,或者使用缩写形式,然后使用allandany将其缩短为长度,以便在控制流语句中使用,例如if.

函数allany通常用于向量化比较的结果,以分别查看所有或任何比较是否为真。这些函数的结果肯定长度为 1,因此它们适用于 if 子句,而矢量化比较的结果则不然。(尽管这些结果适用于ifelse.

最后一个区别:&&and||只评估他们需要的尽可能多的术语(这似乎是短路的意思)。例如,这是一个使用未定义值的比较a;如果它没有短路,就像&|不一样,它会给出一个错误。

a
# Error: object 'a' not found
TRUE || a
# [1] TRUE
FALSE && a
# [1] FALSE
TRUE | a
# Error: object 'a' not found
FALSE & a
# Error: object 'a' not found

最后,请参阅The R Inferno中的第 8.2.17 节,标题为“and and andand”。

于 2011-07-02T19:13:54.540 回答
45

关于“短路”的答案可能具有误导性,但有一些道理(见下文)。在 R/S 语言中,&&||计算第一个参数中的第一个元素。无论第一个值如何,向量或列表中的所有其他元素都将被忽略。这些运算符旨在与if (cond) {} else{}构造一起工作并指导程序控制,而不是构建新的向量。&|运算符旨在处理向量,因此它们将“并行”应用,可以说,沿着最长的争论。在进行比较之前,需要对两个向量进行评估。如果向量的长度不同,则执行较短参数的循环。

当评估&&or的参数时||,存在“短路”,如果从左到右连续的任何值是确定的,则评估停止并返回最终值。

> if( print(1) ) {print(2)} else {print(3)}
[1] 1
[1] 2
> if(FALSE && print(1) ) {print(2)} else {print(3)} # `print(1)` not evaluated
[1] 3
> if(TRUE && print(1) ) {print(2)} else {print(3)}
[1] 1
[1] 2
> if(TRUE && !print(1) ) {print(2)} else {print(3)}
[1] 1
[1] 3
> if(FALSE && !print(1) ) {print(2)} else {print(3)}
[1] 3

只有当参数需要很长时间才能评估时,才会出现短路的优势。当参数是处理较大对象或具有更复杂的数学运算的函数时,通常会发生这种情况。

于 2011-07-02T19:15:44.243 回答
31

&&并且||是所谓的“短路”。这意味着如果第一个操作数足以确定表达式的值,它们将不会计算第二个操作数。

例如,如果第一个操作数&&为假,那么计算第二个操作数就没有意义,因为它不能改变表达式的值(false && true并且false && false都是假的)。||当第一个操作数为真时也是如此。

您可以在此处阅读有关此内容的更多信息:http ://en.wikipedia.org/wiki/Short-circuit_evaluation从该页面上的表格中,您可以看到这&&相当于AndAlsoVB.NET,我假设您指的是。

于 2011-07-02T19:00:38.050 回答