Булевы операторы && и ||
Согласно определению R-языка различие между &
и &&
(соответственно |
и ||
) состоит в том, что первое векторизовано, а второе - нет.
Согласно тексту справки, я читаю разницу, близкую к разнице между "И" и "AndAlso" (соответственно "Or" и "OrElse")... Значение: Это не все оценки, если они не должны быть (т.е. A или B или C всегда истинны, если A истинно, поэтому прекратите оценку, если A истинно)
Может ли кто-то пролить свет здесь? Кроме того, есть AndAlso и OrElse в R?
Ответы
Ответ 1
Более короткие векторы вектора, то есть они могут возвращать вектор, например:
((-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
.
Одно окончательное различие: &&
и ||
оценивают только столько терминов, сколько им нужно (что, по-видимому, означает короткое замыкание). Например, здесь сравнение с использованием значения undefined 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
Наконец, см. раздел 8.2.17 в The R Inferno, озаглавленный "and and and and".
Ответ 2
Ответ о "short-circuiting" потенциально вводит в заблуждение, но имеет некоторую правду (см. ниже). На языке 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
Ответ 3
&&
и ||
- это то, что называется "короткое замыкание". Это означает, что они не будут оценивать второй операнд, если первого операнда достаточно, чтобы определить значение выражения.
Например, если первый операнд в &&
является ложным, тогда нет смысла оценивать второй операнд, так как он не может изменить значение выражения (false && true
и false && false
оба являются ложными). То же самое относится к ||
, когда первый операнд истинен.
Подробнее об этом вы можете узнать здесь: http://en.wikipedia.org/wiki/Short-circuit_evaluation Из таблицы на этой странице вы можете видеть, что &&
эквивалентен AndAlso
в VB. NET, который, как я полагаю, вы имеете в виду.