perl: оператор "//"? - PullRequest
       9

perl: оператор "//"?

23 голосов
/ 14 сентября 2011

У меня есть вопрос об использовании оператора "//", мой код тестирования выглядит следующим образом:

perl -e '@arr1=();@arr2=(1,2,3);@arr3=defined(@arr1)?@arr1:@arr2;print "[@arr3]\n"' 

[1 2 3] 

perl -e '@arr1=();@arr2=(1,2,3);@arr3=@arr1//@arr2;print "[@arr3]\n"' 

[0] 

perl -e '$v1=();$v2="123";$v3=defined($v1)?$v1:$v2;print "[$v3]\n"' 

[123] 

perl -e '$v1=();$v2="123";$v3=$v1//$v2;print "[$v3]\n"' 

[123]

мой вопрос: почему использование оператора "//" дает те же результаты, что и использование "define ()?:" В скаляре, но не массив (или хеш)?

Спасибо !!!

Ответы [ 2 ]

20 голосов
/ 14 сентября 2011

Поскольку крайний левый операнд ?:, || или && - или этот вновь обвязанный // thingie - всегда оценивается в логическом контексте, а не в списке, тогда как другие операнды наследуют окружающий контекст.

@a = @b && @c;

означает

if (@b) {
     @a = @c;
} else {
     @a = scalar @b;
}

В то время как

@a = @b || @c;

, а также

@a = @b // @c;

оба означают

означает * * тысячу двадцать-один

if (@b) {
     @a = scalar @b;
} else {
     @a = @c;
}

Единственный способ избавиться от scalar при назначении @b на @a - это использовать ?:

@a = @b ? @b : @c;

что, конечно, означает

if (@b) {
    @a = @b;
} else {
    @a = @c;
}

Существует также свойство, которое ?: может быть lvalue:

(@a > @b ? @a : @b) = @c;

что, конечно, означает

if (@a > @b) {
    @a = @c;
} else {
    @b = @c;
}

EDIT

Реализация @a // @b и ее определение отличаются. Ошибка отправлена. Спасибо.

10 голосов
/ 14 сентября 2011

Это больше связано с defined, чем с //. От perldoc -f defined:

Использование defined для агрегатов (хэшей и массивов) устарело. Используется для сообщения о том, была ли когда-либо выделена память для этого агрегата. Такое поведение может исчезнуть в будущих версиях Perl.

Итак, в вашем первом примере defined(@arr1) ложно; во втором случае defined(@arr1) - это истина, а @arr3 содержит scalar(@arr1). Разница между // и defined($a) ? $a : $b отмечена в perldoc perlop:

Хотя он не имеет прямого эквивалента в C, оператор Perl // связан с его стилем C or. На самом деле, он точно такой же, как ||, за исключением того, что он проверяет определенность левой стороны вместо ее истинности. Таким образом, $a // $b аналогичен defined($a) || $b (за исключением того, что он возвращает значение $a, а не defined($a)) и дает тот же результат, что и defined($a) ? $a : $b (за исключением того, что троичный оператор форма может использоваться как lvalue, тогда как $a // $b не может ). Это очень полезно для предоставления значений по умолчанию для переменных. Если вы действительно хотите проверить, определен ли хотя бы один из $a и $b, используйте defined($a // $b).

(Акцент мой.)

Так, например:

(defined($a) ? $a : $b) = $c;    # This is valid.
($a // $b) = $c;                 # This is not.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...