要約
IF文の動作、ショートサーキット(短絡評価)の話。(←この文字を見て「あー」と思った人は読まなくて大丈夫だと思います)
IF演算子(と、IIF演算子)
UiPath・VB.NETの場合
たとえばこんなWorkflowを想定してみます。
Bに0が入っているので、IF文では「B = 0」はTrueと評価され、結果として「Bが0です」と表示されます。
でもこれ、IFを「関数」と理解すると、本当はおかしいんだぜ?
何故かというと、プログラミングや数学などで言うところの関数は、その内側が先に評価(計算)されないと成り立たないからです。
たとえば、消費税額を計算する、という関数を考えてみます。入力値 i に、10%を掛けるのを「消費税関数」としましょう。(税率が後から変更とかそういう話は枝葉末節なので省略)
さて、100円と200円の品物を買い、消費税額を計算するのは、
消費税関数(100 + 200)
になります。ここで考えてほしいのは、関数の内側では渡されたのが「100 + 200」であるのか、「300」であるのか、あるいは「値に300が入っている変数x」であるのかは関係ないことです。これが関数の動作の大前提となります。
では翻って、上記のIF文はどうか。
IF(B = 0, "Bが0です", (A / B).ToString())
これをマトモに関数として評価すると、「B = 0かどうか(真偽値)」と「"Bが0です" という文字列」と「A / Bを計算して文字列にする(ToString)」の3つが、IFという関数に渡されることになります。
が、__それをバカ正直に実行すると、上記のケースではBは0なので、3つ目の引数を計算する段階で0除算が発生して例外が出ないとおかしい__ことになります。
つまり、VB.NETのIF関数は、実は関数としてはかなりイレギュラーな振る舞いをしているのです。
ExcelのIF関数
これもVB.NETと同じ動作でした。必要ない側の関数、呼ばれません。(本稿を書く前は違うと思ってた、申し訳ない)
Excel VBAのIIF関数
こちらは正しく「関数」なので、IIFの最初の引数の値がTrueになる場合でも、False側の式も評価されます。なので上記のように「絶対呼ばれないルート」でも、実行時に0除算エラーが発生します。
つまり
これを覚えておけばOK
- | IF(IIF)関数の条件部に該当しない式 |
---|---|
VB.NET IF関数 | 評価されない |
Excel IF関数 | 評価されない |
VBA IIF関数 | 評価される |
余談:短絡評価の話
当たり前の話ですが、
A or B or C
の条件判断で、AがTrueであれば、その時点で上記の条件はTrueになります。つまりBやCの値がどうであろうと変わらず、それを判断する必要がないことになります。そこで、(言語|実行環境)によっては、上記のようなケースで、式全体が確定したら、不要な部分は評価を行わない(実行しない)ことがあります。これを__短絡評価__と呼びます。ただし、通常これが適用されるのは演算子に対してであり、関数の引数ではありません。
VB.NETのIF文はというと、.NET Frameworkの仕様上、C#(言語)との整合性をとる必要があり、C#を含むC系列の言語では所謂「三項演算子」で同じような表記をするため、そちらの動作にあわせたものと思います。Excelは知らん。
VB.NETの
IF(A = B, C, D)
は、C系列の言語だと、
A == B ? C : D
と記載します。こちらは関数ではなく演算子なので、短絡評価を適用できる、ということですね。
更に余談で、VB.NETには、 And とか、 Or という演算子がありますが、これらは__短絡評価はしない__仕様になっています。
かわりに、 AndAlso とか OrElse というのがあり、こちらは短絡評価をしてくれます。
すなわち、XがBoolean型だとして、
True Or X
のときは、Xが評価されますが、
True OrElse X
では、OrElseより前がTrueなので全体としてTrueになることが確定されるため、Xは評価されません。
このあたりの評価方式や考え方は、UiPathでのワークフロー構築にも当然役に立ちますので、覚えておいて損はないと思います!