((-2:2) >= 0) & ((-2:2) <= 0)
# [1] FALSE FALSE TRUE FALSE FALSE
((-2:2) >= 0) && ((-2:2) <= 0)
# [1] FALSE
all
和any
将其缩减为长度为1,以便在控制流语句(如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的,则可以使用任何一种形式,并且您正确地选择了“短路”的原因。但请注意,确保您百分之百确定它们只能是长度为1。否则,您可能会遇到非常奇怪的错误。 - Aaron left Stack Overflow?is.R
中给出了典型的例子,用于检查您是否正在运行R或S-Plus。if(exists(“is.R”)&& is.function(is.R)&& is.R())
。如果is.R
不存在,则不要评估is.function(is.R)
,因为它会抛出错误。同样,如果is.R
不是函数,则不要像调用函数一样调用它。 - Richie Cotton&&
和||
仅评估第一个参数中的第一个元素。无论第一个元素的值如何,向量或列表中的所有其他元素都将被忽略。这些运算符旨在与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
news(“R”)
指出,向&&
或||
提供长度大于1的向量已不推荐使用,并且RCore的意图是在R的后续版本中将其变为错误。&&
和 ||
的说法相符。” - Aaron left Stack Overflow&&
的参数是函数且第一个参数为false,则不会评估第二个参数。但对于&
或ifelse
,这种情况并不成立,它们将评估两个参数。 - IRTFMprint
函数评估的副作用被打印出来。1被打印出来是为了表明在那一点上TRUE并不是决定性的。第5个实例中没有将1打印到控制台,因为FALSE对于“&&”表达式是决定性的,因为第二个参数的值并不重要。如果我将if子句的结果分配给一个命名变量,我们可以更清楚地看到情况。 - IRTFM&&
和 ||
被称为“短路”。这意味着,如果第一个操作数足以确定表达式的值,则它们不会计算第二个操作数。
例如,如果 &&
的第一个操作数为 false,则没有必要计算第二个操作数,因为它无法更改表达式的值(false && true
和 false && false
都是 false)。当第一个操作数为 true 时,||
同样适用。
您可以在此处阅读更多信息:http://en.wikipedia.org/wiki/Short-circuit_evaluation。从该页面的表格中,您可以看到 &&
相当于 VB.NET 中的 AndAlso
,我假设您正在引用它。
f <- function() { print('hello'); TRUE }; FALSE && f()
。将其改为 &
并注意到函数被评估。QED. (翻译者注:QED 是拉丁文 "quod erat demonstrandum" 的缩写,意思是“证毕”。) - Theo&&
和||
会短路是正确的。但在短格式和长格式之间的比较中,这只是一个相对较小的点;更重要的是要理解每个输入向量时它们各自的作用。 - Aaron left Stack OverflowF & {message("Boo!");T}
和 F && {message("Boo!");T}
。 - mbq运算符&&
/||
和&
/|
之间有三个相关的差异,这些差异在官方文档中有解释。以下是摘要:
&
和|
是向量化的这意味着如果您想对向量执行逐元素逻辑操作,则应使用&
和|
:
a = c(TRUE, TRUE, FALSE, FALSE)
b = c(TRUE, FALSE, TRUE, FALSE)
a | b
# [1] TRUE TRUE TRUE FALSE
a || b
# [1] TRUE
&&
和 ||
逻辑运算符在使用时会丢弃第一个元素后面的所有元素。最近版本的 R 在对长度大于1的向量使用这两个运算符时会生成一个有用的警告信息:
In a || b : 'length(x) = 4 > 1' in coercion to 'logical(1)'
&&
和 ||
是被短路的被短路指的是只有在左侧无法决定表达式结果时,才会对右侧进行求值。几乎所有编程语言都在条件操作中这样做,因为它可以在写if
条件语句时使用便捷的惯用语,例如:
if (length(x) > 0L && x[1L] == 42) …
这段代码依赖于短路计算:如果没有短路计算,那么如果x
为空,代码将失败,因为右侧尝试访问不存在的元素。如果没有短路计算,我们将不得不使用嵌套的if
块,导致更冗长的代码:
if (length(x) > 0L) {
if (x[1L] == 42) …
}
if
,while
)中,即使不需要短路,您也应该始终使用&&
和||
。这更符合惯用法,并导致更统一的代码。&
和|
可以执行位运算&
和|
实际上执行位运算而不是布尔运算。也就是说,对于两个整数a
和b
,a & b
计算按位与,a | b
计算按位或。对于布尔值,按位和逻辑操作之间没有区别;但对于任意整数,结果不同。例如,在大多数编程语言中,1 | 2 == 3
。&
和|
的数字参数强制转换为逻辑值并执行布尔运算。raw
类型:c(1, 3) | c(2, 4)
# [1] TRUE TRUE
as.raw(c(1, 3)) | as.raw(c(2, 4))
# [1] 03 07
raw
参数调用操作符 !
(逻辑非)和 xor
时,它们也会执行位运算。&&
或||
将产生警告:
&&
和||
的行为与未指定“其他语言”不评估第二个参数当第一个参数确定时不同。 - IRTFM