これはちょうど現れました:if
ステートメントから抜け出すにはどうすればいいですか?私は長いif文を持っていますが、早い段階で脱出できる状況が1つあります。
ループでこれを行うことができます:
while (something ) {
last if $some_condition;
blah, blah, blah
...
}
ただし、ifステートメントでも同じことができますか?
if ( some_condition ) {
blah, blah, blah
last if $some_other_condition; # No need to continue...
blah, blah, blah
...
}
if
ステートメントをブロック内に配置でき、ブロックから抜け出すことができます。
{
if ( some_condition ) {
...
last if $some_other_condition; # No need to continue...
blah, blah, blah
...
}
}
または、サブルーチンを作成することができます(おそらくプログラム的にはより良いでしょう):
if ( some_condition ) {
run_subroutine();
}
sub run_subroutine {
blah, blah, blah
return if $some_other_condition;
blah, blah, blah
...
}
しかし、if
条件を終了する方法はありますか?
私が誰かのコードを手伝っていたので、質問が出ました。かなり長いif
ステートメントの中に、他のいくつかのif
ステートメントが埋め込まれていました。コードは次のようになりました。
if ( $condition1 ) {
blah, blah, blah;
if ( not $condition2 ) {
blah, blah, blah;
if ( not $condition3 ) {
blah, blah, blah;
}
}
}
これを行うことで、全体がより読みやすくなると思いました。
if ( $condition1 ) {
last if $condition2;
blah, blah, blah;
last if $condition3;
blah, blah, blah;
}
これは、if
ステートメントの通常のフローが標準であることを示していますが、特定の条件下では、if
またはlast
ループでnext
またはwhile
を使用してループを終了するように、for
ステートメントが早期に終了しました。
mpapec's ラベルを使用することの解決策-ラベル自体を使用しない場合でも。ラベルは私のif
の説明です:
IF-UNDER-CONDITION1:
{
if ( $condition1 ) {
last if $condition2;
blah, blah, blah;
last if $condition3;
blah, blah, blah;
}
}
これは標準のコーディング手法ではありませんが、コードの流れは十分に明らかであるため、典型的な低レベルのPerl開発者(私が去った後にこのコードを維持しなければならない開発者)はコードが何をしているかを把握し、維持することができます。彼らはその過程で何かを学ぶかもしれません。
basic block を使用できます。これは、last
、next
、およびredo
の影響を受けるため、それからブレークする可能性があります。
if ($condition) {EXIT_IF:{
last EXIT_IF; # break from code block
print "never get's executed\n";
}}
EXIT_IF: {
if ($condition) {
last EXIT_IF; # break from code block
print "never get's executed\n";
}
}
空のfor()
ループ内に配置し、if
の後にANDで区切るすべての場所に_last;
_を追加します。少しいですが、動作します。トリックを説明するコメントを必ず追加してください。
_for (;;) {
if (condition) {
#code
last if another_condition;
}
last;
}
_
goto
を使用し、そのgotoのループの後にステートメントにラベルを付けます。永遠にのろわれます。
if
内の追加ブロック(例:if () {{ code }}
)。初心者にとっては読みにくいかもしれませんが、コメントがあれば大丈夫です。
独自のソリューション:if
をブロックします。読みやすさに関してはあまり明白ではありません。
独自のソリューション:リターン付きサブルーチン。
率直に言って、サブを呼び出すコストがパフォーマンス的に賢明でない限り、これは可読性に関する限り最もクリーンなソリューションです。
次のように、残りのif
ブロックを別のif
ステートメントの中に入れることができます。
if (some_condition) {
blah, blah, blah
if (!$some_other_condition) {
blah, blah, blah
...
}
}
「続行しますか?」に基づいてシーケンシャルifステートメントを使用する傾向があります。代わりに変数。きみの
if ( $condition1 ) {
blah, blah, blah;
if ( not $condition2 ) {
blah, blah, blah;
if ( not $condition3 ) {
blah, blah, blah;
}
}
}
に再配置することができます
my $ok = $condition1;
if ($ok) {
blah, blah, blah;
$ok = not $condition2;
}
if ($ok) {
blah, blah, blah;
$ok = not $condition3;
}
if ($ok) {
blah, blah, blah;
}
DVKの答え に触発されて遊んでみたところ、少なくともPerl 5.26.1で動作するこのバリアントを思いつきました。
for( ; some_condition ; last ) {
blah, blah, blah
last if $some_other_condition; # No need to continue...
blah, blah, blah
}
perlsyn
ごとに、これは次と同等です:
while (some_condition) {
blah, blah, blah
last if $some_other_condition; # No need to continue...
blah, blah, blah
} continue {
last;
}
continue
ブロックでは、last
はメインループで実行された場合と同じ効果があります。したがって、ループはsome_condition
に応じて0回または1回実行されます。
Perl -E 'my ($cond, $other)=(X, Y);
for(;$cond;last) { say "hello"; last if $other; say "goodbye" }'
さまざまなX
およびY
値に対して、次の結果があります。
X Y Prints
-----------------------
0 0 (nothing)
0 1 (nothing)
1 0 hello, goodbye
1 1 hello
別の方法は、匿名サブルーチンを使用することです。
注:この方法はお勧めしません追加されたスコープの複雑さ(下記の注を参照)。それは可能な答えの完全性のためだけです。
if( $true_condition ){
(sub{
return if $true_condition;
...
})->();
}
注:ルーチン内で宣言された変数は、our
の代わりにmy
を使用する必要があります。コードの残り
while
ループを保持して、last
を使用できるようにしますが、ループが1回だけ実行されるようにします
my $loop_once = 1;
while ( $loop_once-- and some_condition ) {
blah, blah, blah
last if $some_other_condition; # No need to continue...
blah, blah, blah
...
}