すべてのプログラミング言語にはブール短絡評価がありますか?
-
22-07-2019 - |
質問
PHPコード内
if(a() && b())
第1オペランドが false
と評価されると、 b()
は評価されません。
同様に、
if (a() || b())
第1オペランドが true
と評価された場合、 b()
は評価されません。
これは、Java、C#などのすべての言語に当てはまりますか?
これは使用したテストコードです。
<?php
function a(){
echo 'a';
return false;
}
function b(){
echo 'b';
return true;
}
if(a() && b()){
echo 'c';
}
?>
解決
これは、短絡評価と呼ばれます。
通常、Cから派生した言語(C、C ++、Java、C#)には当てはまりますが、すべての言語に当てはまるわけではありません。
たとえば、VB6はこれを実行しません。また、VB.NETの初期バージョンでも実行されませんでした。 VB8(Visual Studio 2005)は、 AndAlso を導入しましたこの目的のための OrElse 演算子。
>また、コメントから、cshは問題をさらに混乱させるために右から左に短絡評価を実行するようです。
短絡評価(または不足)には注意すべき危険があることも指摘しておく必要があります。たとえば、2番目のオペランドが副作用のある関数である場合、プログラマーが意図したとおりにコードが実行されない可能性があります。
他のヒント
VB6には当てはまりません。
VB.netでは、「AndAlso」を使用する必要があります。 &quot; And&quot;の代わりに2番目の式の評価をスキップする場合。
これは、JAVA、C#などのすべての言語に当てはまりますか?
C#では、これは短絡演算子 ' ||
'および '&amp;&amp;
'にのみ当てはまります。 ' |
'または '&amp;
'を使用する場合、毎回両側を評価します。
短絡評価と呼ばれ、ほとんどの言語がこれを実行します。一部の言語では、これを行わない演算子が存在します。
Pascalの元のバージョンはそうではなく、多くの悲しみを引き起こしました。 Delphiなどのモダンパスカルは、Cなどと同じように機能します。
Adaには、特別な短絡形式の条件があります:
and then
or else
このように使用:
if p.next /= null and then p.next.name = 'foo'
if x = 0 or else 1/x = y
ある意味では、プログラマーは式を短絡する必要があることを知っていて、条件式が偶然に機能していないと推測できるので、ちょっといいです。
「子供」である言語には当てはまります。 Cの:PHP、Java、C ++、C#、...、またはPerlと同じ「インスピレーション」で。
ただし、VBには当てはまりません(少なくとも.NETの前に、新しいキーワードが導入されました)。
(そして、それはあなたがVBで最初に作業するのを本当に妨げています^^)
Microsoft VBScript (多くの場合、 'Classic' ASPと組み合わせて)ブール演算子の短絡評価は行われず、代わりにビットごとの評価が使用されます。これは、おそらく史上最悪の言語である可能性のある多くの理由の1つです!
&quot; VBScriptは 論理的ではありません。 VBScriptはビット単位です。すべて いわゆる論理演算子が機能する ブール値ではなく、数値で! ない、そして、または、XOr、Eqv、Imp all 引数を4バイトに変換します 整数、論理演算を実行します 整数のビットの各ペア、および 結果を返します。 Trueが-1の場合 Falseが0の場合、すべてが機能します。 -1はすべてのビットがオンになっているため また、0はすべてのビットがオフになります。しかし 他の数字が入った場合、すべて ベットはオフになっています&quot;。
このブログから入手。 Ericリッパー。
Delphiでは、コンパイラオプションです。
これはJavaにも当てはまりますが、演算子|、&amp;などは両側を評価します。
Erlangでは、 and
および or
演算子は短絡評価を行いません。短絡動作が必要な場合は、 orelse
および and
演算子を使用する必要があります。
標準のFORTRANまたはFortranでは、ブール式のオペランドは任意の順序で評価できます。不完全な評価は許可されますが、実装は定義されています。
これにより、厳密な左から右への順序付けが強制された場合に許可されないブール式の最適化が可能になります。厳密な順序付けが必要な式は、個別の条件に分解する必要があります。そうでない場合、実装依存の仮定を行うことができます。
分解は順序付けを強制するために使用されるため、個別のIFステートメントを常に単一の式に最適化できるとは限りません。ただし、短絡評価は分解を伴う明示的なものであり、これは遅延評価を可能にするために厳密な左から右への順序付けを強制する言語よりも決して悪くありません。
言語はFORTRAN(Fortran、BASIC、VBn)から派生しており、FORTRANに似た効率を実現するように設計された言語(Pascal、Ada)は、最初は順不同の評価を許可するFORTRANの例に従いました。
ほとんどの言語(私が見たすべての言語)は、&amp;&amp;などの条件演算子で短絡評価を使用します。および||。条件の1つが要件を満たした時点で、評価を停止します。 (&amp;&amp;の最初のfalse。||の最初のtrue)
&amp;などのすべてのBINARY演算子および|、処理されます。 (オリジナル)
&amp;などのすべてのBITWISE演算子および|、処理されます。 (編集:5/10/17)
これは短絡評価と呼ばれ、VB、VB.NET、Fortranを除く、これまでに働いたすべての言語(C、C ++、C#、Java、Smalltalk、Javascript、Lisp)に共通です。
これは実際には非常に便利な機能です。短絡がなければ、これを行うことはできません:
if (a != null && a.isBlank())
短絡がなければ、ifステートメントがネストされている必要があります。これは、aがnullの場合、2番目の部分がエラーをスローするためです。
Coldfusionは、短絡評価をネイティブに行います。すべてのCF開発者が書いていると確信しています:
<cfif isdefined("somevariable") and somevariable eq something>
//do logic
</cfif>
他の回答では、短絡評価を使用した場合と使用しない場合の言語の良い例が示されているので、繰り返しません。
追加する興味深い点が1つあります。ClojureなどのLispにはブール値の短絡評価がありますが、さらに、マクロを使用して短絡評価で any 演算子を非常に簡単に定義できます。
短絡「nand」の例; Clojureでの操作:
(defmacro nand
([x]
`(not ~x))
([x & xs]
`(let [nand# (not ~x)]
(if nand#
true ; short circuit if we can prove the nand is true
(nand ~@xs))))) ; continue with the other expressions otherwise
(nand true true)
=> false
(nand false (println "Expression with a side effect!"))
=> true