演算子
Dart は以下の表に示す演算子をサポートしています。この表は、Dart の演算子の結合性と、最高から最低までの演算子の優先順位を示しており、Dart の演算子の関係の近似値です。これらの多くの演算子はクラスメンバとして実装できます。
説明 | 演算子 | 結合性 |
---|---|---|
単項後置 | expr ++ expr -- () [] ?[] . ?. ! | なし |
単項前置 | - expr ! expr ~ expr ++ expr -- expr await expr | なし |
乗算 | * / % ~/ | 左 |
加算 | + - | 左 |
シフト | << >> >>> | 左 |
ビットごとの AND | & | 左 |
ビットごとの XOR | ^ | 左 |
ビットごとの OR | | | 左 |
関係演算子と型テスト | >= > <= < as is is! | なし |
等値 | == != | なし |
論理 AND | && | 左 |
論理 OR | || | 左 |
if-null | ?? | 左 |
条件 | expr1 ? expr2 : expr3 | 右 |
カスケード | .. ?.. | 左 |
代入 | = *= /= += -= &= ^= など | 右 |
スプレッド (注を参照) | ... ...? | なし |
演算子を使用すると、式が作成されます。演算子式の例をいくつか示します。
a++
a + b
a = b
a == b
c ? a : b
a is T
演算子の優先順位の例
#演算子の表では、各演算子はそれ以降の行にある演算子よりも高い優先順位を持ちます。たとえば、乗算演算子%
は、等値演算子==
よりも高い優先順位を持ち(したがって、それよりも先に実行され)、等値演算子==
は、論理AND演算子&&
よりも高い優先順位を持ちます。この優先順位により、次の2行のコードは同じように実行されます。
// Parentheses improve readability.
if ((n % i == 0) && (d % i == 0)) ...
// Harder to read, but equivalent.
if (n % i == 0 && d % i == 0) ...
算術演算子
#Dart は、次の表に示すような通常の算術演算子をサポートしています。
演算子 | 意味 |
---|---|
+ | 加算 |
- | 減算 |
- expr | 単項マイナス(負)、別名否定(式の符号を反転) |
* | 乗算 |
/ | 除算 |
~/ | 整数結果を返す除算 |
% | 整数除算の剰余を取得する(剰余) |
例
assert(2 + 3 == 5);
assert(2 - 3 == -1);
assert(2 * 3 == 6);
assert(5 / 2 == 2.5); // Result is a double
assert(5 ~/ 2 == 2); // Result is an int
assert(5 % 2 == 1); // Remainder
assert('5/2 = ${5 ~/ 2} r ${5 % 2}' == '5/2 = 2 r 1');
Dart は、前置と後置のインクリメントおよびデクリメント演算子もサポートしています。
演算子 | 意味 |
---|---|
++ var | var = var + 1 (式の値はvar + 1 ) |
var ++ | var = var + 1 (式の値はvar ) |
-- var | var = var - 1 (式の値はvar - 1 ) |
var -- | var = var - 1 (式の値はvar ) |
例
int a;
int b;
a = 0;
b = ++a; // Increment a before b gets its value.
assert(a == b); // 1 == 1
a = 0;
b = a++; // Increment a after b gets its value.
assert(a != b); // 1 != 0
a = 0;
b = --a; // Decrement a before b gets its value.
assert(a == b); // -1 == -1
a = 0;
b = a--; // Decrement a after b gets its value.
assert(a != b); // -1 != 0
等値および関係演算子
#次の表は、等値および関係演算子の意味を示しています。
演算子 | 意味 |
---|---|
== | 等しい; 以下の説明を参照 |
!= | 等しくない |
> | より大きい |
< | より小さい |
>= | 以上 |
<= | 以下 |
2つのオブジェクト x と y が同じものを表しているかどうかをテストするには、==
演算子を使用します。(2つのオブジェクトが全く同じオブジェクトかどうかを知る必要があるまれなケースでは、代わりにidentical()関数を使用します。)==
演算子の動作は次のとおりです。
xまたはyがnullの場合、両方がnullであればtrueを、一方だけがnullであればfalseを返します。
引数yでxの
==
メソッドを呼び出した結果を返します。(そうです、==
などの演算子は、最初のオペランドで呼び出されるメソッドです。詳細については、演算子を参照してください。)
等値および関係演算子のそれぞれを使用する例を次に示します。
assert(2 == 2);
assert(2 != 3);
assert(3 > 2);
assert(2 < 3);
assert(3 >= 3);
assert(2 <= 3);
型テスト演算子
#as
、is
、is!
演算子は、実行時に型をチェックするのに便利です。
演算子 | 意味 |
---|---|
as | 型キャスト(ライブラリプレフィックスの指定にも使用) |
is | オブジェクトが指定された型を持つ場合にtrue |
is! | オブジェクトが指定された型を持たない場合にtrue |
obj is T
の結果は、obj
がT
で指定されたインターフェースを実装する場合にtrueになります。たとえば、obj is Object?
は常にtrueです。
オブジェクトが型T
であると確信している場合にのみ、as
演算子を使用してオブジェクトを特定の型にキャストします。例
(employee as Person).firstName = 'Bob';
オブジェクトが型T
であるかどうかわからない場合は、オブジェクトを使用する前にis T
を使用して型をチェックします。
if (employee is Person) {
// Type check
employee.firstName = 'Bob';
}
代入演算子
#すでに見たように、=
演算子を使用して値を代入できます。代入先の変数がnullの場合にのみ代入するには、??=
演算子を使用します。
// Assign value to a
a = value;
// Assign value to b if b is null; otherwise, b stays the same
b ??= value;
+=
などの複合代入演算子は、演算と代入を組み合わせます。
= | *= | %= | >>>= | ^= |
+= | /= | <<= | &= | |= |
-= | ~/= | >>= |
複合代入演算子の動作は次のとおりです。
複合代入 | 同等の式 | |
---|---|---|
演算子opの場合 | a op = b | a = a op b |
例 | a += b | a = a + b |
次の例では、代入演算子と複合代入演算子を使用しています。
var a = 2; // Assign using =
a *= 3; // Assign and multiply: a = a * 3
assert(a == 6);
論理演算子
#論理演算子を使用して、ブール式を反転または組み合わせることができます。
演算子 | 意味 |
---|---|
! expr | 次の式を反転する(false を true に、true を false に変更する) |
|| | 論理 OR |
&& | 論理 AND |
論理演算子を使用する例を次に示します。
if (!done && (col == 0 || col == 3)) {
// ...Do something...
}
ビット演算とシフト演算子
#Dart では、数値の個々のビットを操作できます。通常、これらのビット演算とシフト演算子は整数で使用します。
演算子 | 意味 |
---|---|
& | AND |
| | OR |
^ | XOR |
~ expr | 単項ビットごとの補数(0 は 1 に、1 は 0 になる) |
<< | 左シフト |
>> | 右シフト |
>>> | 符号なし右シフト |
ビット演算子とシフト演算子の使用方法の例を次に示します。
final value = 0x22;
final bitmask = 0x0f;
assert((value & bitmask) == 0x02); // AND
assert((value & ~bitmask) == 0x20); // AND NOT
assert((value | bitmask) == 0x2f); // OR
assert((value ^ bitmask) == 0x2d); // XOR
assert((value << 4) == 0x220); // Shift left
assert((value >> 4) == 0x02); // Shift right
// Shift right example that results in different behavior on web
// because the operand value changes when masked to 32 bits:
assert((-value >> 4) == -0x03);
assert((value >>> 4) == 0x02); // Unsigned shift right
assert((-value >>> 4) > 0); // Unsigned shift right
条件式
#Dartには、それ以外ではif-else文が必要となる可能性のある式を簡潔に評価できる2つの演算子が用意されています。
condition
?
expr1
:
expr2
- conditionがtrueの場合、expr1を評価し(その値を返します)、それ以外の場合は、expr2を評価し、その値を返します。
expr1
??
expr2
- expr1がnullでない場合、その値を返します。それ以外の場合は、expr2を評価し、その値を返します。
ブール式に基づいて値を代入する必要がある場合は、条件演算子?
と:
を使用することを検討してください。
var visibility = isPublic ? 'public' : 'private';
ブール式がnullをテストする場合は、if-null演算子??
(null合体演算子とも呼ばれます)の使用を検討してください。
String playerName(String? name) => name ?? 'Guest';
前の例は、少なくとも他の2つの方法で記述できますが、これほど簡潔ではありません。
// Slightly longer version uses ?: operator.
String playerName(String? name) => name != null ? name : 'Guest';
// Very long version uses if-else statement.
String playerName(String? name) {
if (name != null) {
return name;
} else {
return 'Guest';
}
}
カスケード表記
#カスケード(..
、?..
)を使用すると、同じオブジェクトに対して一連の操作を行うことができます。インスタンスメンバへのアクセスに加えて、同じオブジェクトのインスタンスメソッドを呼び出すこともできます。これにより、多くの場合、一時変数の作成の手順が省かれ、より流動的なコードを記述できます。
次のコードを考えてみましょう。
var paint = Paint()
..color = Colors.black
..strokeCap = StrokeCap.round
..strokeWidth = 5.0;
コンストラクタPaint()
はPaint
オブジェクトを返します。カスケード表記に続くコードはこのオブジェクトに対して動作し、返される可能性のある値は無視されます。
前の例は、次のコードと同等です。
var paint = Paint();
paint.color = Colors.black;
paint.strokeCap = StrokeCap.round;
paint.strokeWidth = 5.0;
カスケードが動作するオブジェクトがnullになる可能性がある場合は、最初の操作にnull短縮カスケード(?..
)を使用します。?..
で開始すると、そのnullオブジェクトに対してカスケード操作が実行されないことが保証されます。
querySelector('#confirm') // Get an object.
?..text = 'Confirm' // Use its members.
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed!'))
..scrollIntoView();
前のコードは次のコードと同等です。
var button = querySelector('#confirm');
button?.text = 'Confirm';
button?.classes.add('important');
button?.onClick.listen((e) => window.alert('Confirmed!'));
button?.scrollIntoView();
カスケードをネストすることもできます。例:
final addressBook = (AddressBookBuilder()
..name = 'jenny'
..email = 'jenny@example.com'
..phone = (PhoneNumberBuilder()
..number = '415-555-0100'
..label = 'home')
.build())
.build();
実際オブジェクトを返す関数でカスケードを構築することに注意してください。たとえば、次のコードは失敗します。
var sb = StringBuffer();
sb.write('foo')
..write('bar'); // Error: method 'write' isn't defined for 'void'.
sb.write()
呼び出しはvoidを返し、void
に対してカスケードを構築することはできません。
スプレッド演算子
#スプレッド演算子は、コレクションを生成する式を評価し、結果の値を展開して、別のコレクションに挿入します。
スプレッド演算子は実際には演算子式ではありません。...
/...?
構文はコレクションリテラル自体の一部です。そのため、スプレッド演算子については、コレクションページで詳細を確認できます。
演算子ではないため、構文には"演算子の優先順位"がありません。事実上、最も低い「優先順位」を持ちます。つまり、次のようなあらゆる種類の式がスプレッドターゲットとして有効です。
[...a + b]
その他の演算子
#残りの演算子のほとんどは、他の例で説明しました。
演算子 | 名前 | 意味 |
---|---|---|
() | 関数適用 | 関数呼び出しを表します。 |
[] | 添字アクセス | オーバーライド可能な[] 演算子への呼び出しを表します。例:fooList[1] は、インデックス1 の要素にアクセスするために、int1 をfooList に渡します。 |
?[] | 条件付き添字アクセス | [] に似ていますが、左側のオペランドはnullになる可能性があります。例:fooList?[1] は、fooList がnullでない限り(その場合は式はnullになります)、インデックス1 の要素にアクセスするためにint1 をfooList に渡します。 |
. | メンバアクセス | 式のプロパティを参照します。例:foo.bar は、式foo からプロパティbar を選択します。 |
?. | 条件付きメンバアクセス | . に似ていますが、左側のオペランドはnullになる可能性があります。例:foo?.bar は、foo がnullでない限り(その場合はfoo?.bar の値はnullになります)、式foo からプロパティbar を選択します。 |
! | 非nullアサーション演算子 | 式を基になる非null型にキャストし、キャストに失敗した場合はランタイム例外をスローします。例:foo!.bar は、foo がnullでないことをアサートし、プロパティbar を選択します。foo がnullの場合はランタイム例外がスローされます。 |
.
、?.
、および..
演算子の詳細については、クラスを参照してください。
特に明記されていない限り、このサイトのドキュメントはDart 3.5.3を反映しています。ページの最終更新日は2024年3月15日です。 ソースを表示 または 問題を報告する。