根据R输入语言定义,之间的差&
和&&
(相应地|
和||
)是,前者被矢量而后者则不是。
根据帮助文本,我读到了与“ And”和“ AndAlso”(相应地为“ Or”和“ OrElse”)之间的区别类似的含义……含义:并非所有评估都必须是(即,如果A为true,则A或B或C始终为true,因此,如果A为true,则停止评估)
有人可以照亮这里吗?另外,R中是否有AndAlso和OrElse?
根据R输入语言定义,之间的差&
和&&
(相应地|
和||
)是,前者被矢量而后者则不是。
根据帮助文本,我读到了与“ And”和“ AndAlso”(相应地为“ Or”和“ OrElse”)之间的区别类似的含义……含义:并非所有评估都必须是(即,如果A为true,则A或B或C始终为true,因此,如果A为true,则停止评估)
有人可以照亮这里吗?另外,R中是否有AndAlso和OrElse?
Answers:
较短的向量被向量化,这意味着它们可以返回向量,如下所示:
((-2:2) >= 0) & ((-2:2) <= 0)
# [1] FALSE FALSE TRUE FALSE FALSE
较长的形式仅检查每个向量的第一个元素就从左到右求值,因此以上给出
((-2:2) >= 0) && ((-2:2) <= 0)
# [1] FALSE
就像帮助页面所说的那样,这使得较长的形式“适合编程控制流,并且[在]子句中通常是首选的”。
因此,仅在确定向量的长度为一时,才想使用长格式。
您应该绝对确定向量仅是长度1,例如在它们是仅返回长度1布尔值的函数的情况下。如果向量的长度可能大于1,则要使用缩写形式。因此,如果您不确定,则应该先检查,或者使用缩写形式,然后使用all
并将any
其减小为长度,以便在控制流语句中使用,例如if
。
函数all
和any
通常用于向量化比较的结果,以分别查看所有比较或所有比较是否为真。这些函数的结果肯定为1,因此它们适合在if子句中使用,而向量化比较的结果则不然。(尽管这些结果适用于ifelse
。
最后一个区别:&&
和||
仅评估所需数量的项(这似乎是短路)。例如,这是使用未定义值的比较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”。
c(TRUE, FALSE)
,并且该if
语句不清楚。如果确定所有长度都为1,则可以,两者之一都可以,并且您正确地认为“短路”是首选长度的原因。不过请注意,请确保您100%确保它们只能是长度1。否则,您可能会得到一些愚蠢的错误。
?is.R
用于检查您是否正在运行R或S-Plus。 if(exists("is.R") && is.function(is.R) && is.R())
。如果is.R
不存在,则您不希望评估,is.function(is.R)
因为它将抛出错误。同样,如果is.R
不是函数,则不要像调用函数那样调用它。
关于“短路”的答案可能会引起误解,但有一定道理(见下文)。在R / S语言,&&
并且||
仅评估在第一个参数的第一个元素。向量或列表中的所有其他元素都将被忽略,无论第一个值如何。那些运算符旨在与if (cond) {} else{}
构造一起工作,并直接控制程序,而不是构造新的向量。&
和和|
运算符旨在对向量进行工作,因此可以说,它们将“并行”应用在向量的长度上最长的争论。在进行比较之前,都需要评估两个向量。如果向量的长度不相同,则执行较短参数的循环。
当对&&
或的参数进行||
求值时,存在“短路”,即如果从左到右连续的任何值都是确定性的,则求值停止,并返回最终值。
> 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
短路的优势只有在参数需要花费很长时间进行评估时才会出现。当参数是处理较大对象的函数或具有更复杂的数学运算的函数时,通常会发生这种情况。
&&
和一致||
。
&&
是函数,而第一个参数为false,则不会计算第二个参数。对于任何一个都不是正确的,&
否则ifelse
将对两个参数都求值。
&&
而||
在所谓的“短路”。这意味着,如果第一个操作数足以确定表达式的值,则他们将不会评估第二个操作数。
例如,如果to的第一个操作数&&
为false,则评估第二个操作数没有意义,因为它不能更改表达式的值(false && true
并且false && false
都为false)。第||
一个操作数为true时也是如此。
您可以在此处阅读有关此内容的更多信息:http : //en.wikipedia.org/wiki/Short-circuit_evaluation从该页面上的表中,您可以看到&&
与AndAlso
VB.NET中的等效,我假设您所指的是VB.NET。
f <- function() { print('hello'); TRUE }; FALSE && f()
。转到&
并注意该函数已被评估。QED。
&&
并且||
短路。但这在短格式和长格式之间的比较中确实是一个次要的问题;了解输入为向量时每个函数的作用更为重要。
F & {message("Boo!");T}
和F && {message("Boo!");T}
。