Difference between revisions of "If/ja"

From Second Life Wiki
< If
Jump to navigation Jump to search
m
m
 
(3 intermediate revisions by 3 users not shown)
Line 1: Line 1:
{{Multi-lang}}
{{Multi-lang|If|/ja}}
{{#vardefine:p__desc|
{{#vardefine:p__desc|
}}{{#vardefine:p_condition_desc|もし実行して真なら'''branch'''が実行されます。
}}{{#vardefine:p_condition_desc|もし実行して真なら'''branch'''が実行されます。
Line 12: Line 12:
|statement_title=if ( {{LSL Param|condition}} ) {{LSL Param|branch}}
|statement_title=if ( {{LSL Param|condition}} ) {{LSL Param|branch}}
|extras=
|extras=
{{!}}
<div id="box">
<div id="box">
== if ( {{LSL Param|condition_d|condition}} ) {{LSL Param|branch|branch_true}} else {{LSL Param|branch|branch_false}} ==
== if ( {{LSL Param|condition_d|condition}} ) {{LSL Param|branch|branch_true}} else {{LSL Param|branch|branch_false}} ==
Line 21: Line 20:
{{LSL DefineRow||branch_false|{{#var:p_branch_desc}}}}
{{LSL DefineRow||branch_false|{{#var:p_branch_desc}}}}
{{!}}}
{{!}}}
「else-if」チェーンには、もはや制限がないようです(または非常に高い > 120)
</div>
</div>
</div>
</div>
Line 26: Line 27:
{{{!}} style="border-width: 0px;border-spacing: 0px;"
{{{!}} style="border-width: 0px;border-spacing: 0px;"
{{!}}
{{!}}
<pre>
<source lang="lsl2">// 簡単な手順でのifを呼び出す方法
// 簡単な手順でのifを呼び出す方法
integer test()
integer test() {
{
     llOwnerSay("Test method called!");
     llOwnerSay("Test method called!");
   
     return TRUE;
     return TRUE;
}
}


default {
default
     touch_start(integer total_number) {
{
         if (FALSE && test()) { // もし短絡的な最適がされていた場合、test()が呼ばれることは無いでしょう。
     touch_start(integer total_number)
            // Will never get here.
    {
         if (FALSE && test())
        { // もし短絡的な最適がされていた場合、test()が呼ばれることは無いでしょう。
          // 実行されることがない
         }
         }
     }
     }
}
}</source>
</pre>
{{!}}}
{{!}}}
短絡な言語では、AND(&&)の左側がFALSEなら、右側はどんな値であろうとテストされることなくFALSEを返すでしょう。 LSLは短絡的ではないので、常に左と右の両方がテストされます。もしネストされた構造を使用した場合のシミュレートはこうなるでしょう。
短絡評価を行なう言語では、論理演算 AND (&&) の左側が FALSE だった場合、右側は決して評価されません。なぜなら右側の値が何であろうと、全体の評価は常に FALSE となるからです。LSL は短絡評価を行なわないので、左右いずれもが常に評価されます。短絡評価を行ないたい場合は、以下のようにネストした if 文で代替できます:
<pre>
<source lang="lsl2">default
default {
{
     touch_start(integer total_number) {
     touch_start(integer total_number)
         if (FALSE) {
    {
             if (test()) {
         if (FALSE)
        {
             if (test())
            {
               // 実行されることがない
               // 実行されることがない
             }
             }
         }
         }
     }
     }
}
}</source>
</pre>
|examples=簡単なインラインのifステートメント:
|examples=簡単なインラインのifステートメント:
<pre>
<pre>
Line 119: Line 123:
この条件では字下げによって、ifステートメントにより両方のllSayコマンドが操作されるかのように見えます。実際には、もし <code>a</code> が"Joe"と同義なら、常に"I don't know what it means either..."と発言するでしょう。。。
この条件では字下げによって、ifステートメントにより両方のllSayコマンドが操作されるかのように見えます。実際には、もし <code>a</code> が"Joe"と同義なら、常に"I don't know what it means either..."と発言するでしょう。。。


===The {{=}}/{{=}}{{=}} Mistakes===
「==」演算子と「=」演算子を混同することは一般的なエラーであり、無知や単純なタイプミスによるものです。例えば、
<source lang="lsl2">if (av_id = llGetOwner())//<-- This is likely a mistake
        llSay(0,"It's my owner!");</source>
av_idの値が何であれ、メッセージを送信するでしょう。なぜなら、それはif(llGetOwner())と等しいからです。
Cプログラマーたちが何年も前に考案したトリックがあり、このバグを回避する方法です。比較の前に定数や他の代入できない式(たとえば、関数呼び出しやある操作の結果など)を置く習慣をつけることです。これにより、この誤りから守られます。これは非常に深刻なエラーであり、大規模なコードでデバッグするのが難しいことがあります。
<source lang="lsl2">if(llGetOwner() == av_id)
          llSay(0,"It's my owner!");</source>
この場合、間違いはコンパイルエラーを引き起こすことになります。
<source lang="lsl2">if(llGetOwner() = av_id)//<-- will not compile
          llSay(0,"It's my owner!");</source>
構文チェッカー[[lslint]]は、この使用法に遭遇した際に警告を報告します(警告を抑制するには、文を括弧で囲むことです)。しかし、読者に意図した動作を伝える最良の方法は、同じ行にコメントを追加することです。
<source lang="lsl2">if ((av_id = llGetOwner()))//<-- この構文は、構文チェッカーに対してこれが意図された動作であることを伝えます。
        llSay(0,"It's my owner!");</source>


|helpers
|helpers
Line 129: Line 155:
|mode
|mode
|deprecated
|deprecated
|cat1=Conditional/ja
|cat1=Conditional
|cat2=Flow Control/ja
|cat2=
|cat3
|cat3
|cat4
|cat4
}}
}}

Latest revision as of 08:47, 26 September 2023

if ( condition ) branch

•  condition もし実行して真ならbranchが実行されます。
•  branch シングルステートメント、ブロックステートメント、空のステートメントの何れかが可能です。

if ( condition ) branch_true else branch_false

•  condition もし実行して真ならbranch_trueが実行され、それ以外の場合branch_falseが実行されます。
•  branch_true シングルステートメント、ブロックステートメント、空のステートメントの何れかが可能です。
•  branch_false シングルステートメント、ブロックステートメント、空のステートメントの何れかが可能です。

「else-if」チェーンには、もはや制限がないようです(または非常に高い > 120)

詳細

条件の種類
条件
integer 0ではない場合は真。
float 0ではない場合は真。
string 文字列の長さが0ではない場合は真。
key keyが有効でNULL_KEYではない場合のみ真。
vector vectorがZERO_VECTORではない場合は真。
rotation rotationがZERO_ROTATIONではない場合は真。
list listの長さが0ではない場合は真。正しい動作は、Monoでコンパイルされたスクリプトのみで見られ、LSOでコンパイルされたスクリプトは誤って false になります。BUG-230728

LSLの演算は短絡しません。たとえば:

// 簡単な手順でのifを呼び出す方法
integer test()
{
    llOwnerSay("Test method called!");
    return TRUE;
}

default
{
    touch_start(integer total_number)
    {
        if (FALSE && test())
        { // もし短絡的な最適がされていた場合、test()が呼ばれることは無いでしょう。
          // 実行されることがない
        }
    }
}

短絡評価を行なう言語では、論理演算 AND (&&) の左側が FALSE だった場合、右側は決して評価されません。なぜなら右側の値が何であろうと、全体の評価は常に FALSE となるからです。LSL は短絡評価を行なわないので、左右いずれもが常に評価されます。短絡評価を行ないたい場合は、以下のようにネストした if 文で代替できます:

default
{
    touch_start(integer total_number)
    {
        if (FALSE)
        {
            if (test())
            {
              // 実行されることがない
            }
        }
    }
}

簡単なインラインのifステートメント:

if (a == 1) c = b;

簡単なブロックifステートメント:

if (a == 1)
{
    // 何らかの処理
}

連なったif/elseブロック (この例では一つの行のみ発言するでしょう)

if (a == "Loren") {
    llSay(0, "Lorem ipsum sic amet!");
} else if (a == "Bob") {
    llSay(0, "Babble dabble rabble rouse.");
} else {
    llSay(0, "Gobbledygook?  or English?");
}

複合的なifステートメント:

if (a == 1 && b == c)
{
    // ここで何らかの処理
}

ネストされたifステートメント:

if (a == 1)
{
    if (b == c)
    {
        // ここで何らかの処理
    }
}

セミコロンの置き間違いに気をつけましょう。奇妙なことを起こしてしまうでしょう。 もしifステートメントとコードブロックの間にセミコロンを置いた場合、ifステートメントはブロックの実行操作ができないでしょう。実例:

if (a == "Loren");
{
    llSay(0, "Lorem ipsum sic amet!");
}

このコードは以下の方法で実行できるでしょう。

  1. if (a == "Loren");行は、セミコロンが、これが一行のifステートメントだとLSLに教えることで実行するでしょう。
  2. そして、コードブロックの開始部と実行させるコンテンツが同じなら、たとえifステートメントよりも前に何が来ようとも、このケースでは"Lorem ipsum sic amet!"と発言します。

中括弧を忘れた場合は別の問題が発生します。

if (a == "Loren")
    llSay(0, "Lorem ipsum sic amet!");
    llSay(0, "I don't know what it means either...");

この条件では字下げによって、ifステートメントにより両方のllSayコマンドが操作されるかのように見えます。実際には、もし a が"Joe"と同義なら、常に"I don't know what it means either..."と発言するでしょう。。。

The =/== Mistakes

「==」演算子と「=」演算子を混同することは一般的なエラーであり、無知や単純なタイプミスによるものです。例えば、

if (av_id = llGetOwner())//<-- This is likely a mistake
         llSay(0,"It's my owner!");

av_idの値が何であれ、メッセージを送信するでしょう。なぜなら、それはif(llGetOwner())と等しいからです。

Cプログラマーたちが何年も前に考案したトリックがあり、このバグを回避する方法です。比較の前に定数や他の代入できない式(たとえば、関数呼び出しやある操作の結果など)を置く習慣をつけることです。これにより、この誤りから守られます。これは非常に深刻なエラーであり、大規模なコードでデバッグするのが難しいことがあります。

if(llGetOwner() == av_id)
          llSay(0,"It's my owner!");

この場合、間違いはコンパイルエラーを引き起こすことになります。

if(llGetOwner() = av_id)//<-- will not compile
          llSay(0,"It's my owner!");

構文チェッカーlslintは、この使用法に遭遇した際に警告を報告します(警告を抑制するには、文を括弧で囲むことです)。しかし、読者に意図した動作を伝える最良の方法は、同じ行にコメントを追加することです。

if ((av_id = llGetOwner()))//<-- この構文は、構文チェッカーに対してこれが意図された動作であることを伝えます。
         llSay(0,"It's my owner!");