Определены некоторые строковые значения ("0", "" и ""), но (== undef) - PullRequest
4 голосов
/ 07 февраля 2020

В моем скрипте perl я использовал условие if ($a == undef), я думал, что оно такое же, как if (not defined $a), где $a - это строка, прочитанная из файла CSV. Однако я заметил, что определены несколько строковых значений ("", " ", "0", "-0", "+0", "@", "a", а также много других пробелов и специальных символов), но также undef. Если undef только для числовых значений c, оно должно передавать "0", "+0" и "-0". Кто-нибудь может объяснить? Теперь я понимаю, что не следует использовать if ($a == undef) для замены if (not defined $a).

Мой код тестирования:

@a_array = ("-1", "-0", "0", "+0", "1", "", " ", "@", "a", "\$", "-");
undef $a;
test_a();

foreach $a (@a_array) {
    $len_a = length($a);
    test_a();
}

sub test_a {
    if (defined $a) { print "a = $a is defined;  "} else {print "a = $a not defined; "}; 
    if ($a == undef) { print "a = $a (== undef);  "} else {print "a = $a (!= undef); "}; 
    if (length($a) > 0){ print "length of a is $len_a > 0 \n"} else {print "length of a is $len_a !> 0 \n"};
}

1 Ответ

7 голосов
/ 07 февраля 2020

Perl имеет два оператора равенства: == и eq. == проверяет, является ли числовая форма c каждого значения численно равной. eq проверяет, является ли строковая форма каждого значения лексикографически равной. undef не является строкой или числом, и если используется как строка, она эквивалентна пустой строке, если используется как число, она эквивалентна 0 (как пустая строка и любая строка, которая не начинается с чем-то, что выглядит как число). Когда это происходит, вы обычно получаете предупреждения.

Для проверки на undef тест на эквивалентность не требуется: используйте определенную функцию *1010*. Только если оно определено, оно может иметь значащую строку или числовое значение, и вы можете выполнять последующие тесты.

Функция length возвращает undef при передаче undef, так что если вы Если вы хотите знать, если скаляр определен и не имеет длины 0, вам нужна только одна логическая проверка: if (length $x). 0 и undef оба являются ложными результатами. Обратите внимание, что до Perl 5.12 это вызывало бы предупреждение, поскольку length undef пытался использовать undef в качестве строки, как eq.

...