演算子
式
ColdFusion の式は、オペランドと演算子で構成されます。定数と変数はオペランドです。乗算記号などの演算子は、オペランドに対して作用する動詞です。関数も演算子の一種と見なすことができます。
最も基本的な式は単一のオペランドで構成され、演算子がありません。複雑な式は複数の演算子とオペランドで構成されます。ColdFusion の式の例を次に示します。
12 MyVariable a++ (1 + 1)/2 "father" & "Mother" Form.divisor/Form.dividend Round(3.14159)
演算子はオペランドに対して作用します。引数が 1 つだけの関数など、一部の演算子にはオペランドが 1 つしかありません。算術演算子や論理演算子など、多くの演算子にはオペランドが 2 つあります。オペランドが 2 つある式は、一般に次のように記述します。
Expression Operator Expression
式の間に演算子を置きます。それぞれの式は、単純なオペランド(変数または定数)にすることも、演算子と式で構成されるサブ式にすることも可能です。サブ式を使用すれば複雑な式が作成できます。例えば、式 (1 + 1)/2 の場合、1 + 1 は 1 つの演算子と 2 つのオペランドで構成されるサブ式です。
演算子のタイプ
ColdFusion には、5 つのタイプの演算子があります。
- 算術
- ブール値
- 決定(比較)
- 文字列
- 三項
関数も、オペランドに対して作用するので演算子と見なすことができます。
算術演算子
次の表で、算術演算子について説明します。
|
説明 |
---|---|
+ - * / |
加減乗除をおこなうための基本的な算術演算子です。除算の場合は、右側のオペランドに 0 を指定できません。 |
++ – |
インクリメントおよびデクリメント。変数を 1 だけ増減します。変数を増減した後に式で使用する場合は、「x = ++ i」のように記述します。これをプリインクリメントまたはプリデクリメントと呼びます。逆に、式で使用した後に変数を増減する 場合は、 「x = i++」のように記述します。これをポストインクリメントまたはポストデクリメントと呼びます。例えば、変数 i の初期値が 7 である場合、x = ++i とすると、式の評価後 x の値は 8 になりますが、x=i とすると x の値は 7 になります。いずれの場合も、 i の 値は 8 になります。これらの演算子は、f().a のように、関数が含まれている式では使用できません。また、-x のような式は使用できますが、---x や +x は意味があいまいであるため、エラーになります。このような場合は、-(--x) や (++x) のように、括弧を使用して演算子をグループ化できます。 |
+= -= *= /= %= |
複合代入演算子。右辺の変数が、式の要素および結果変数の両方として使用されます。したがって、a += b という式は a = a + b と同じです。 |
+ - |
単項算術演算子。数値の符号を設定します。 |
MODまたは % |
モジュロ。数値を除数で割った余りを返します。その結果には、除数と同じ符号が付きます。演算子の右側の値には整数を使用してください。数字以外の値を使用するとエラーが発生します。実数を指定した場合は小数部分が無視されます。例えば、11 MOD 4.7 は 3 になります。 |
|
整数の除算。整数を別の整数で割ります。結果も整数になります。例えば、9¥4 は 2 になります。右側のオペランドには 0 を指定できません。 |
^ |
指数。指数で累乗した結果を返します。キャレット文字(^)は数字と指数の間に挿入します。例えば、2^3 は 8 になります。基数および指数には実数や負の値も使用できます。ただし、-1^.5 のように虚数になる式の結果は、文字列 "-1.#IND になります。ColdFusion では、虚数および複素数はサポートされていません。 |
ブール演算子
ブール(論理)演算子は、論理結合子および否定の演算を実行します。ブール演算子のオペランドは、ブール値(True/False)です。次の表で、ブール演算子について説明します。
演算子 |
説明 |
---|---|
NOT または ! |
引数の値を反転します。例えば、NOT True は False、NOT False は True です。 |
AND または && |
両方の引数が True の場合は True を返します。そうでない場合は False を返します。例えば、True AND True は true です が、True AND False は False です。 |
OR または || |
引数のいずれか一方でも True である場合は True を返します。そうでない場合は False を返します。例えば、True OR False は True ですが、False OR False は False です。 |
XOR |
排他的論理和(eXclusive OR)。1 つの引数のみが True である場合は True を返します。そうでない場合は False を返します。両方の引数が True または False である場合は False を返します。例えば、True XOR True は False ですが、True XOR False は True です。 |
EQV |
等価(Equivalence)。両方のオペランドが True または False である場合は True を返します。EQV 演算子は XOR 演算子の逆です。例えば、True EQV True は True ですが、True EQV False は False です。 |
IMP |
包含(Implication)。ステートメント「A IMP B」は、論理ステートメント「A ならば B」と同値です。 A IMP B は、 A が True で B が False の場合にのみ False になります。そうでない場合はすべて True です。 |
決定演算子
ColdFusion の決定(比較)演算子は、結果としてブール値 True/False を生成します。多くの演算には、等価な演算子形式が複数存在します。例えば、IS と EQ は同じ演算を実行します。次の表で、決定演算子について説明します。
演算子 |
説明 |
---|---|
IS EQUAL |
大文字と小文字を区別しないで、2 つの値を比較します。2 つの値が同じである場合は、True を返します。 |
IS NOT |
IS の逆です。大文字と小文字を区別しないで、2 つの値を比較します。2 つの値が同じでない場合は、True を返します。 |
CONTAINS |
左側の値に右側の値が含まれている場合は、True を返します。 |
DOES NOT CONTAIN |
CONTAINS の逆です。左側の値に右側の値が含まれていない場合は、True を返します。 |
GREATER THAN |
左側の値が右側の値よりも大きい場合は、True を返します。 |
LESS THAN |
GREATER THAN の逆です。左側の値が右側の値よりも小さい場合は、True を返します。 |
GREATER THAN OR EQUAL TO |
左側の値が右側の値よりも大きいか等しい場合は、True を返します。 |
LESS THAN OR EQUAL TO |
左側の値が右側の値よりも小さいか等しい場合は、True を返します。 |
CFScript 式に限り、次の決定演算子も使用できます。これらは、タグ内の式では使用できません。==(EQ)、!=(NEQ)、>(GT)、<(LT)、>=(GTE)、<=(LTE)
決定演算子のルール
決定演算子には、次のルールが適用されます。
- CONTAINS または DOES NOT CONTAIN 以外の決定演算子を含んだ式が評価されるときには、まず、データを数値に変換できるかどうかが判定されます。変換できる場合は、データの数値比較がおこなわれます。変換できない場合は、文字列比較がおこなわれます。これによって、予期しない結果が生成される場合があります。この動作の詳細については、データ型の変換の評価および型変換の問題を参照してください。
CONTAINS または DOES NOT CONTAIN を含んだ式が評価されるときには、文字列比較はおこなわれません。式 A CONTAINS B は、B が A の部分文字列である場合に True と評価されます。したがって、次の式は True です。
123.45 CONTAINS 3.4 |
ColdFusion の決定演算子は、大文字と小文字を区別せずに文字列を比較します。したがって、次の式は True です。
"a" IS "A"
決定演算子で文字列比較がおこなわれる場合は、文字列の左から右に評価され、それぞれの位置で文字のソート順に基づいて判定がおこなわれます。異なる文字が最初に現れた位置で、文字列の関係が判定されます。したがって、次の式は True です。
"abde" LT "ac"
文字列演算子
文字列演算子は文字列を操作します。次の表で、文字列演算子について説明します。
演算子 |
説明 |
---|---|
& |
文字列を連結します。 |
&= |
複合連結。右辺の変数が、連結演算の要素および結果変数の両方として使用されます。したがって、a &= b という式は a = a & b と同等です。1 つの式に含めることができる複合代入演算子は 1 つだけです。 |
クエリオブクエリでは、連結演算子として || を使用します。
三項演算子
三項演算子は、3 つのオペランドを取る決定演算子です。この演算子では、ブール式に基づいて変数に値が代入されます。この演算子の形式は次のようになります。
(Boolean expression)? expression1 : expresson2
ブール式が true と評価された場合、演算子の結果は expression1 となり、true でない場合は expression2 となります。
以下に例を示します。
<cfset c = (a GT b)? a : b >
a が b より大きい場合は、c に a の値が代入されます。そうでない場合は、c に b の値が代入されます。
丸括弧内には、ブール値として評価される式であればどのような式でも入れることができ、a および b には有効な式であればどのような式でも指定できます。この演算子は他の式の中にネストできます。
演算子の優先順位と評価順序
式中の演算子が評価される順序は、演算子の優先順位によって決まります。優先順位は次のとおりです。EQUALS や GREATER THAN OR EQUAL TO など、演算子の代替名の一部は、簡潔のために省略しています。
^ *, / \ MOD +, - & EQ, NEQ, LT, LTE, GT, GTE, CONTAINS, DOES NOT CONTAIN, ==, !=, >, >=, <, <= NOT, ! AND, && OR, || XOR EQV IMP
標準以外の順序で評価するには、式を括弧で囲みます。次に例を示します。
- 6 - 3 * 2 は 0 です。
- (6 - 3) * 2 は 6 です。
括弧はネストできます。式中の演算子の評価順序がわからない場合は、括弧を使用して評価順序を明示してください。
関数を演算子として使用する
関数は演算子の形式の 1 つです。ColdFusion 関数は値を返すので、関数の結果をオペランドとして使用できます。関数引数は式です。例えば、次の式は有効です。
- Rand()
- UCase("This is a text: ") & ToString(123 + 456)
関数のシンタックス
次の表に、関数のシンタックスと使用方法のガイドラインを示します。
使用方法 |
例 |
---|---|
引数なし |
Function() |
基本形式 |
Function(Data) |
関数のネスト |
Function1(Function2(Data)) |
複数の引数 |
Function(Data1, Data2, Data3) |
文字列の引数 |
Function('This is a demo')Function(This is a demo) |
式である引数 |
Function1(X*Y, Function2("Text")) |
<cfset myDate = DateFormat(Now(), "mmmm d, yyyy")>
関数で返される値を直接使用して、複合式を作成できます。次に例を示します。
Abs(Myvar)/Round(3.14159)
式に関数を挿入する方法について詳しくは、# 記号の使用を参照してください。
関数のオプションの引数
必須の引数の後にオプションの引数を取る関数があります。オプションの引数を省略した場合は、デフォルトで、あらかじめ定義された値が使用されます。次に例を示します。
- Replace("Eat and Eat", "Eat", "Drink") は "Drink and Eat" を返します。
- Replace("Eat and Eat", "Eat", "Drink", "All") は "Drink and Drink" を返します。
このように結果が異なるのは、Replace 関数が、置換範囲を指定する 4 番目のオプション引数を持っているからです。そのデフォルト値は "One" なので、1 番目の例では最初の "Eat" のみが "Drink" に置換されます。2 番目の例では、4 番目の引数が指定されているので、すべての "Eat" が "Drink" に置換されます。
式の評価と関数
ColdFusion では、関数が実行される前に、関数の属性が式として評価されます。したがって、関数の属性には ColdFusion 式を指定することができます。例えば、次のようなコードがあるとします。
<cfset myStringVar = UCase(firstVariable & " more sleep!")>
ColdFusion サーバーで 2 行目が実行されるときには、次の処理がおこなわれます。
-
文字列の連結を含んだ式が識別されます。
-
firstVariable 変数 が 文字列 "we all need" として評価されます。
-
文字列 "we all need" と文字列 " more sleep!" が連結されて "we all need more sleep!" が取得されます。
-
文字列 "we all need more sleep!" が UCase 関数に渡されます。
-
文字列の引数 "we all need more sleep!" が UCase 関数で処理され、"WE ALL NEED MORE SLEEP!" が取得されます。
-
変数 myStringVar に文字列値 "WE ALL NEED MORE SLEEP!" が代入されます。
上記の手順 1~3 は、関数が処理される前に実行されます。
1 つの式での複数の代入の使用
代入を連結すると、1 つのステートメントで複数の変数に同じ値を代入できます。これには式の結果の連結代入も含まれます。次のコードは連結代入の例を示しています。
a=b=c=d*5
複数の代入で var 演算子を使用することもできますが、この演算子を含む変数は他の変数よりも前に置く必要があります。次に例を示します。
//The following line is valid. var a = var b = c = d*5 //The following line is not valid. // a = b = var c = d*5
同一性演算子
ColdFusion(2021 リリース)では、同一性演算子(===)が導入されています。2 つの値が同じ型ではない場合は、比較時に false が返されます。オペランドの型が同じで値が等しい場合に、true を返します。
例 1
<cfscript> // e.g. 1 === "1" is false, but 1 === 1 is true function returntrue(){ return true } writeoutput(returntrue() == 'true'); // YES writeoutput(returntrue() == TRUE); // YES writeoutput(returntrue() === 'true'); // NO writeoutput(returntrue() === true); // YES writeoutput(returntrue() === TRUE); // YES </cfscript>
等価/不等価演算子
ColdFusion は、緩く型指定された言語で、変数の型をエンジンがスマートに解釈します。ColdFusion(2018 リリース)では、ColdFusion のデータ型は維持されていますが、下位互換性を保つために、等価演算子は、2 つのオブジェクトを型ではなく値で比較していました。
ColdFusion(2021 リリース)では、厳密な等価性と厳密な不等価性の演算子が導入されました。これにより、== または EQ 演算子に関する問題が解決されます。
例 - 厳密な等価性
<cfscript> writedump(2=="2"); // YES writedump(2==="2"); // NO writedump('yes' == 1); // YES writedump('yes' === 1); // NO writedump(false ==0); // YES writedump(false ===0);//NO </cfscript>
例 - 厳密な不等価性
<cfscript> writedump(2!="2"); // NO writedump(2!=="2"); // YES writedump('yes' != 1); // NO writedump('yes' !== 1);// YES writedump(false !=0); // NO writedump(false !==0);//YES </cfscript>
スプレッド演算子
ColdFusion(2021 リリース)では、スプレッド演算子により、反復可能オブジェクトにアクセスできます。反復可能オブジェクトでは、内部の項目に順に移動することができます。
スプレッド演算子を使用すると、反復可能オブジェクト内の項目にアクセスできます。
スプレッド演算子は、… シンタックスを使用して表すことができます。
シンタックス
...variable
まず、スプレッド演算子の動作例を見てみましょう。
<cfscript> numbers = [1,2,3]; writeDump(sum( ...numbers )); function sum(required x,required y,required z) { return x + y + z; }
出力
6
要するに、スプレッドシンタックスを使用すると、0 個以上の引数(関数呼び出しの場合)または要素(配列リテラルの場合)が必要な箇所で、配列式や文字列などの反復可能オブジェクトを展開することができます。
次に例を示します。
<cfscript> myarray1=[5,6,7] myarray2=[3,4,5,...myarray1] myarray3=[1,2,3,...myarray2] writedump(myarray3) </cfscript>
同様に、スプレッド演算子を使用すると、構造体内でオブジェクトリテラルを複製することができます。スプレッド演算子を使用して、オブジェクトを結合したり、関数に引数を挿入したり、文字列リテラルから文字配列を作成したりすることができます。
次に例を示します。
<cfscript> beatles={ "vocals":"John Lennon", "guitar":"George Harrison", "bass":"Paul McCartney", "drums":"Ringo Starr" } beatlesCopy={...beatles,'justanotherkey':'justanothervalue'} writeDump(beatlesCopy) </cfscript>
配列リテラル
<cfscript> numbers = [1,2,3] list = [...numbers, '4', 'five', 6,...numbers] writeDump(list) </cfscript>
文字列リテラル
<cfscript> arr = [..."12345","foo",..."bar",..."123"]; writeDump(arr) </cfscript>
キーと値のペアを使用した構造体
<cfscript> obj1 ={ foo: 'bar', x: 42 }; obj2 ={ foo: 'baz', y: 13 }; newObj = {...obj1,...obj2}; writeDump(newObj) </cfscript>
スプレッド演算子は、組み込み関数では使用できません。以下のスニペットは、期待どおりには動作しません。
<cfscript>
myarray1=[1,2,3];
myarray= ArrayNew(1, true,"numeric")
writedump(myarray.append(...myarray1).append("4").append("5"))
for (i in myarray){
writeoutput(i)
}
</cfscript>
反復可能オブジェクトの結合
スプレッド演算子を使用すると、他のいくつかの値を結合して 1 つの値にすることができます。
次に例を示します。
<cfscript> s1=["Mick Jagger"] s2=["Keith Richards","Ron Wood"] s3=["Charlie Watts"] // merge the arrays using Spread stones=[...s1,...s2,...s3] writeDump(stones) </cfscript>
別の配列内にスプレッド配列を挿入することもできます。
次に例を示します。
<cfscript> s1=["Mick Jagger"] s2=["Keith Richards","Ron Wood"] s3=["Charlie Watts"] // merge the arrays using Spread stones=["Brian Jones","Bill Wyman",...s1,...s2,...s3] writeDump(stones) </cfscript>
オブジェクトリテラル
<cfscript> foo={ "key1":"val1", "key2":"val2", "key3":"val3" } bar={ "key4":"val4", "key5":"val5" } combo={...foo,...bar} writeDump(combo) </cfscript>
キーが重複している場合は、重複するキーが上書きされます。
<cfscript> foo={ "key1":"val1", "key2":"val2", "key3":"val3" } bar={ "key3":"val4", "key5":"val5" } combo={...foo,...bar} writeDump(combo) </cfscript>
関数
スプレッド演算子を使用して、関数に引数を挿入できます。
<cfscript> function calcVolume(width, height, depth) { writeOutput(width * height * depth) } calcVolume(12, 30, 14) // the usual way cube = [12, 30, 14] // using Spread operator calcVolume(...cube) </cfscript>
レスト演算子
レスト演算子の外見はスプレッド演算子(...)と同じですが、動作は逆です。レスト演算子を使用して、不特定数の引数の配列を作成できます。
次に例を示します。
<cfscript> function myRest(...args){ writeDump(args) } myRest(1,2,3,4,5) </cfscript>
myRest 関数に渡されるすべての引数は、引数配列で使用できるようになりました。
レスト演算子の別の例を見てみましょう。
<cfscript> function myFun(a,b,...otherArgs){ writeOutput(serializeJSON(a)) writeOutput(serializeJSON(b)) writeOutput(serializeJSON(otherArgs)) } myFun("one","two","three","four","five","six","seven","eight") </cfscript>
出力
"one""two"["three","four","five","six","seven","eight"]
レスト演算子は、関数定義の唯一のパラメーターとして使用することも、最後のパラメーターとして使用することもできます。唯一のパラメーターとして使用した場合は、レスト演算子ですべての引数がまとめられます。レスト演算子がリストの末尾で使用されている場合は、残りのすべての引数がまとめられます。
次に例を示します。
<cfscript> function restTest(one,two,...args){ writeDump(one) writeDump(two) writeDump(args) } restTest(1,2,3,4,5) </cfscript>
この例では、最初の 2 つの引数を個別に指定し、残りを配列にまとめます。