Будет ли разница между 42, 42,0, "42,0", "42",
В процессе тестирования моего кода Perl с помощью "Smart Match (~~)" я столкнулся с этой проблемой. Будет ли разница между 42, 42.0, "42.0", "42"
$var1 = "42";
$var2 = "42.0";
$a = $var1 ~~ $var2;
Я получаю $a
как 0; что означает $var1
и $var2
не равны.
Объясните пожалуйста.
Ответы
Ответ 1
Оператор smart match будет "обычно делать то, что вы хотите". Пожалуйста, прочитайте это как "не всегда".
42 ~~ 42.0
возвращает значение true.
42 ~~ "42.0"
также возвращает true: строка сравнивается с числом и поэтому рассматривается как число. То же самое для "42" ~~ 42.0
.
"42" ~~ "42.0"
возвращает false: оба аргумента являются строками, и эти строки не сравниваются как "равные", хотя их численное значение будет. Вы бы не хотели, чтобы Perl отображал "two" ~~ "two-point-oh"
как истинный.
Строка может быть принудительно использована для ее числовой интерпретации путем добавления нуля:
0+"42" ~~ "42.0"
возвращает true снова, так как первая строка принудительно добавляется к числу 42
, а вторая соответствует примеру.
Страница perldoc perlsyn
или perldoc perlop
определяет, как работает интеллектуальное сопоставление:
Object Any invokes ~~ overloading on $object, or falls back:
Any Num numeric equality $a == $b
Num numish[4] numeric equality $a == $b
undef Any undefined !defined($b)
Any Any string equality $a eq $b
Вы можете видеть, что равенство строки является значением по умолчанию.
Ответ 2
Теперь вы можете пересмотреть использование умного соответствия. Текущая реализация рассматривается сообществом Perl как ошибка, среди прочего, из-за вашего вопроса и ответа амона.
Работа продолжается для "более простой" и более простой, но несовместимой версии смарт-соответствия, которая может быть в следующем крупном выпуске Perl (5.18). Он просто запретит ваш пример: $a ~~ $b не будет разрешен, если $b - простое скалярное значение (например, 42 или 42).
Если у вас слишком много времени на руку, вы можете ознакомиться с архивами Perl5, например этот поток.
Ответ 3
Контекстная типизация.
$Var1
и $Var2
в последний раз использовались как строки (в задании), поэтому теперь они ведут себя как строки. ~~
будет выполнять сравнение строк, если оба аргумента являются строками.
Если вы используете один из них в качестве номера - вам даже не нужно назначать ему - тогда он будет вести себя как число, а ~~
будет использовать числовое сравнение. p >
Этот script выведет NO YES
:
my $v1 = "42";
my $v2 = "42.0";
print (($v1 ~~ $v2) ? 'YES ' : 'NO ');
$v1 + 0;
print (($v1 ~~ $v2) ? 'YES ' : 'NO ');
Ссылка для оператора ~~