![](/img/trans.png)
[英]Ternary expression containing loose comparison in else branch yields unexpected result
[英]Ternary operator in perl yields unexpected result when assigning a variable in the statement
我正在嘗試從 php 過渡到 perl 並且預計會遇到一些怪異。 我不明白為什么我的代碼的一個版本與另一個版本相比有效。
這失敗了:
sub tester
{
$return;
($_[0] < 10) ? $return = "youre a youngin" : $return = "youre an old person";
return $return;
}
print "how old are you?";
$a = <>;
chomp $a;
print tester($a); #both result in "youre an old person"
但是這個有效:
sub tester
{
return ($_[0] < 10) ? "youre a youngin" : "youre an old person";
}
print "how old are you?";
$a = <>;
chomp $a;
print tester($a);
這里的真正區別是什么?!
它與 Perl 的運算符優先級有關。 在 Perl 中,
($_[0] < 10) ? $return = "youre a youngin" : $return = "youre an old fart";
和
( ($_[0] < 10) ? $return = "youre a youngin" : $return ) = "youre an old fart";
注意paren綁定到FRONT。
這導致 Perl 的另一個令人困惑的功能:條件左值:您可以這樣做(CONDITION? $ASSIGN_A_IF_CONDITION_IS_TRUE: $ASSIGN_B_IF_CONDITION_IS_FALSE) = 2
這是一個修復
($_[0] < 10) ? ($return = "youre a youngin") : ($return = "youre an old fart");
編輯:
然而,大多數人會寫
$return = ($_[0] < 10) ? "youre a youngin" : "youre an old fart";
,節省了兩次鍵入變量的冗余。
根據Perl和Z2FEC392304A5C23AC138DA222847F9B7CZ DOCS ?:
Z0114AD0114AD0111D7282728F1836FE12FE12522323232323232323232312574EFY44Z ?:
(http://perldoc.perl.org/perlop.html) (http://php.net/manual/en/language.operators.precedence.ZE1BFD762321E409CEE4AC0B6E841963C)
啊,你已經發現了為什么?:
是一個壞主意,除了在微不足道的情況下。
運算符優先級是問題所在。 你很可能想要這樣做:
$return = ($_[0] < 10) ? "you're a youngin'" : "you're an old fart";
不過,您的代碼還有一些其他問題。
my
運算符明確執行此操作。use strict
和use warnings
。 這些編譯指示禁用了古老的 Perl 惡作劇,並警告可能是錯誤的可疑操作。@_
; 沒有什么理由直接在 function 中使用$_[0]
。 (這樣做很危險,因為@_
是別名;您可以更改調用者的變量!)所以你可能想要更像這樣的東西:
use strict;
use warnings;
sub tester {
my ($age) = @_;
if ($age < 10) {
return "you're a youngin'";
}
else {
return "you're an old fart";
}
}
print "how old are you? ";
my $age = <>;
chomp $age;
print tester($age);
請注意, my $x =...
聲明了一個變量並分配了一個值,而my ($x, $y, $z) =...
聲明了多個變量並將一個列表解壓縮到其中。
my
變量稱為詞法變量,僅存在於您聲明它們的塊中; 它們不像 PHP 變量那樣是函數范圍的。 實際上,您可能應該只在perlsub中閱讀它們。
如果你寫:
sub tester
{
return ($_[0] < 10) ? "You're a young'un" : "You're an oldie";
}
然后你會得到你期望的結果。
這是一個優先事項。
($_[0] < 10) ? ($return = "youre a youngin") : ($return = "youre an old fart");
...效果更好。
但老實說,沒有一個認真的 Perl 程序員會這樣寫。 首先,他們會將以下內容放在程序的頂部:
use warnings;
use strict;
其次,他們會將論點放入本地:
sub tester {
my $arg = shift;
第三,他們會以以下兩種方式之一編寫條件:
if ($arg < 10) {
$return = "you're a youngin";
}
else {
$return = "you're an old fart";
}
如果他們來自 Lisp 背景,他們可能會省去 $return 變量而只寫:
return $arg < 10 ? "you're a youngin" : "you're an old fart";
基本上,運算符優先級。
我相信$return;
是語法錯誤。 您不需要聲明它 - perl 和 php 中的變量是無范圍的。
此外=
優先於?:
因此您需要將()
添加到兩個分配中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.