Этот фрагмент кода Perl в моей программе дает неправильный результат.
$condition ? $a = 2 : $a = 3 ;
print $a;
Независимо от значения $condition
, выход всегда равен 3, как получилось?
Этот фрагмент кода Perl в моей программе дает неправильный результат.
$condition ? $a = 2 : $a = 3 ;
print $a;
Независимо от значения $condition
, выход всегда равен 3, как получилось?
Это объясняется в документации Perl .
Из-за приоритета оператора Perl оператор анализируется как
($condition ? $a= 2 : $a ) = 3 ;
Поскольку оператор?: дает присваиваемый результат, 3 присваивается результат условия.
Когда $condition истинно, это означает ($ a = 2) = 3, давая $a = 3
Когда $condition является ложным, это означает ($ a) = 3, давая $a = 3
Правильный способ написать это
$a = ( $condition ? 2 : 3 );
print $a;
Мы были укушены этим на работе, поэтому я размещаю здесь, надеясь, что другие найдут это полезным.
Как только у вас есть подозрение, что вы можете страдать от проблем с приоритетом, трюк, чтобы понять, что, по мнению Перла, вы имели в виду:
perl -MO=Deparse,-p -e '$condition ? $a= 2 : $a= 3 ; print $a;'
В вашем случае это покажет вам:
(($condition ? ($a = 2) : $a) = 3);
print($a);
-e syntax OK
... в этот момент вы должны сказать "о, это объясняет"!
Просто чтобы продлить предыдущий ответ... Если по какой-либо причине назначения должны быть частью условного выражения, вы должны написать его следующим образом:
$condition ? ($a=2) : ($a=3);
Это было бы полезно, если бы вы назначали разные переменные на основе условия.
$condition ? ($a=2) : ($b=3);
И если вы выберете переменную, но при этом присвоите одно и то же, независимо от того, что вы могли бы сделать:
($condition ? $a : $b) = 3;
Из-за приоритета оператора Perl оператор анализируется как:
($condition ? $a = 2 : $a ) = 3 ;
Поскольку оператор?: дает присваиваемый результат, 3 присваивается результат условия.
Когда $condition истинно, это означает, что $a = 2 = 3 дает $a = 3
Когда $condition является ложным, это означает, что $a = 3 дает $a = 3
Правильный способ написать это
$a = $condition ? 2 : 3;
В общем, вам действительно нужно привыкнуть использовать условные обозначения для выполнения задания, как в исходном примере - это то, что приводит к тому, что Perl получает репутацию только для записи.
Хорошее эмпирическое правило состоит в том, что условные выражения относятся только к простым значениям, а не к выражениям с побочными эффектами. Когда вам или кому-то еще нужно прочитать этот код через восемь месяцев, вы бы предпочли, чтобы он читал вот так?
$x < 3 ? foo($x) : bar($y);
Или как это?
if ($x < 3) {
$foo($x);
} else {
$bar($y);
}
Одно предложение Титония ответить выше:
Если вы хотите присвоить разные значения одной и той же переменной, это может быть лучше (путь к копировальной книге):
$a = (условие $)? 2: 3;