メインコンテンツにスキップ

演算子

Dart は、次の表に示す演算子をサポートしています。この表は、Dart の演算子の結合規則と 演算子の優先順位 を高い順に示しており、Dart の演算子関係の概算です。これらの演算子の多くを クラスのメンバーとして実装 できます。

説明演算子結合規則
単項後置expr++    expr--    ()    []    ?[]    .    ?.    !なし
単項前置-expr    !expr    ~expr    ++expr    --expr      await exprなし
乗算*    /    %  ~/
加算+    -
シフト<<    >>    >>>
ビットごとの AND&
ビットごとの XOR^
ビットごとの OR|
関係および型テスト>=    >    <=    <    as    is    is!なし
等価==    !=なし
論理 AND&&
論理 OR||
null非包含??
条件expr1    ?    expr2    :    expr3
連鎖..    ?..
代入=    *=    /=   +=   -=   &=   ^=   など
展開 (注参照)...    ...?なし

演算子を使用すると、式が作成されます。演算子式の例を次に示します。

dart
a++
a + b
a = b
a == b
c ? a : b
a is T

演算子の優先順位の例

#

演算子表では、各演算子はそれ以降の行の演算子よりも優先順位が高くなります。たとえば、乗算演算子 % は、等価演算子 == よりも優先順位が高く (したがって先に実行されます)、等価演算子 == は、論理 AND 演算子 && よりも優先順位が高くなります。この優先順位により、次の 2 行のコードは同じように実行されます。

dart
// Parentheses improve readability.
if ((n % i == 0) && (d % i == 0)) {
  // ...
}

// Harder to read, but equivalent.
if (n % i == 0 && d % i == 0) {
  // ...
}

算術演算子

#

Dart は、通常の算術演算子をサポートしています。次の表に示します。

演算子意味
+加算
-減算
-expr単項マイナス、または否定とも呼ばれます (式の符号を反転します)
*乗算
/除算
~/整数結果を返す除算
%整数除算の剰余を取得します (モジュロ)

dart
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 は、前置および後置のインクリメントおよびデクリメント演算子もサポートしています。

演算子意味
++varvar  =  var + 1 (式の値は var + 1)
var++var  =  var + 1 (式の値は var)
--varvar  =  var - 1 (式の値は var - 1)
var--var  =  var - 1 (式の値は var)

dart
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() 関数を使用してください。) == 演算子は次のように機能します。

  1. x または y が null の場合、両方とも null なら true を返し、片方のみ null なら false を返します。

  2. x で引数 y を持つ == メソッドの呼び出し結果を返します。(そのとおり、== のような演算子は、最初のオペランドで呼び出されるメソッドです。詳細については、演算子を参照してください。)

等価演算子および関係演算子の各使用例を次に示します。

dart
assert(2 == 2);
assert(2 != 3);
assert(3 > 2);
assert(2 < 3);
assert(3 >= 3);
assert(2 <= 3);

型テスト演算子

#

asis、および is! 演算子は、実行時に型をチェックするのに便利です。

演算子意味
as型キャスト (また、ライブラリプレフィックスを指定するためにも使用されます)
isオブジェクトが指定された型である場合は true
is!オブジェクトが指定された型でない場合は true

obj is T の結果は、objT によって指定されたインターフェイスを実装している場合は true になります。たとえば、obj is Object? は常に true です。

as 演算子を使用して、オブジェクトがその型であることを確信できる場合にのみ、オブジェクトを特定の型にキャストします。例:

dart
(employee as Person).firstName = 'Bob';

オブジェクトが T 型であることを確信できない場合は、オブジェクトを使用する前に is T を使用して型をチェックしてください。

dart
if (employee is Person) {
  // Type check
  employee.firstName = 'Bob';
}

代入演算子

#

すでに確認したように、= 演算子を使用して値を代入できます。代入先の変数が null の場合にのみ代入するには、??= 演算子を使用します。

dart
// Assign value to a
a = value;
// Assign value to b if b is null; otherwise, b stays the same
b ??= value;

+= のような複合代入演算子は、操作と代入を組み合わせます。

=*=%=>>>=^=
+=/=<<=&=|=
-=~/=>>=

複合代入演算子の動作は次のとおりです。

複合代入等価な式
演算子 op の場合a op= ba = a op b
a += ba = a + b

次の例では、代入演算子および複合代入演算子を使用しています。

dart
var a = 2; // Assign using =
a *= 3; // Assign and multiply: a = a * 3
assert(a == 6);

論理演算子

#

論理演算子を使用して、ブール式を反転または結合できます。

演算子意味
!expr次の式を反転します (false を true に、true を false に変更します)
||論理 OR
&&論理 AND

論理演算子を使用した例を次に示します。

dart
if (!done && (col == 0 || col == 3)) {
  // ...Do something...
}

ビット演算子およびシフト演算子

#

Dart では、数値の個々のビットを操作できます。通常、これらのビット演算子およびシフト演算子は整数と共に使用されます。

演算子意味
&AND
|OR
^XOR
~expr単項ビットごとの補数 (0 は 1 に、1 は 0 になります)
<<左シフト
>>右シフト
>>>符号なし右シフト

ビット演算子およびシフト演算子を使用した例を次に示します。

dart
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 の値を評価して返します。

ブール式に基づいて値を代入する必要がある場合は、条件演算子 ? および : の使用を検討してください。

dart
var visibility = isPublic ? 'public' : 'private';

ブール式が null をテストする場合は、null 非包含演算子 ?? (null 合体演算子とも呼ばれる) の使用を検討してください。

dart
String playerName(String? name) => name ?? 'Guest';

前の例は、少なくとも 2 つの他の方法で記述できましたが、それほど簡潔ではありませんでした。

dart
// 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';
  }
}

連鎖記法

#

連鎖 (..?..) を使用すると、同じオブジェクトに対して一連の操作を実行できます。インスタンスメンバーにアクセスするだけでなく、その同じオブジェクトでインスタンスメソッドを呼び出すこともできます。これにより、一時変数の作成ステップが節約され、より流暢なコードを記述できるようになります。

次のコードを検討してください。

dart
var paint = Paint()
  ..color = Colors.black
  ..strokeCap = StrokeCap.round
  ..strokeWidth = 5.0;

コンストラクタ Paint()Paint オブジェクトを返します。連鎖記法の後のコードは、このオブジェクトに対して操作を行い、返される可能性のある値は無視します。

前の例は、このコードと同等です。

dart
var paint = Paint();
paint.color = Colors.black;
paint.strokeCap = StrokeCap.round;
paint.strokeWidth = 5.0;

連鎖が操作するオブジェクトが null の可能性がある場合は、最初の操作でnull 短縮連鎖 (?..) を使用してください。?.. から開始すると、null オブジェクトに対して連鎖操作が試行されないことが保証されます。

dart
document.querySelector('#confirm') // Get an object.
  ?..textContent =
      'Confirm' // Use its members.
  ..classList.add('important')
  ..onClick.listen((e) => window.alert('Confirmed!'))
  ..scrollIntoView();

前のコードは、次のコードと同等です。

dart
final button = document.querySelector('#confirm');
button?.textContent = 'Confirm';
button?.classList.add('important');
button?.onClick.listen((e) => window.alert('Confirmed!'));
button?.scrollIntoView();

連鎖をネストすることもできます。たとえば:

dart
final addressBook =
    (AddressBookBuilder()
          ..name = 'jenny'
          ..email = 'jenny@example.com'
          ..phone =
              (PhoneNumberBuilder()
                    ..number = '415-555-0100'
                    ..label = 'home')
                  .build())
        .build();

連鎖を実際のオブジェクトを返す関数で構築するように注意してください。たとえば、次のコードは失敗します。

dart
var sb = StringBuffer();
sb.write('foo')
  ..write('bar'); // Error: method 'write' isn't defined for 'void'.

sb.write() の呼び出しは void を返し、void で連鎖を構築することはできません。

展開演算子

#

展開演算子は、コレクションを生成する式を評価し、結果の値を展開して、別のコレクションに挿入します。

展開演算子は実際には演算子式ではありません.../...? 構文は、コレクションリテラル自体の一部です。したがって、展開演算子については、コレクションページで詳細を確認できます。

演算子ではないため、構文には「演算子の優先順位」はありません。事実上、最も低い「優先順位」を持ちます。つまり、展開ターゲットとしては、あらゆる種類の式が有効です。

dart
[...a + b]

その他の演算子

#

残りの演算子のほとんどは、他の例で確認しています。

演算子名前意味
()関数適用関数呼び出しを表します
[]添字アクセスオーバーライド可能な [] 演算子への呼び出しを表します。例: fooList[1] は、インデックス 1 の要素にアクセスするために整数 1fooList に渡します。
?[]条件付き添字アクセス[] と同様ですが、左端のオペランドが null になる可能性があります。例: fooList?[1] は、fooList が null でない限り (その場合、式は null に評価されます)、インデックス 1 の要素にアクセスするために整数 1fooList に渡します。
.メンバーアクセス式のプロパティを参照します。例: foo.bar は、式 foo からプロパティ bar を選択します。
?.条件付きメンバーアクセス. と同様ですが、左端のオペランドが null になる可能性があります。例: foo?.bar は、foo が null でない限り (その場合、foo?.bar の値は null になります)、式 foo からプロパティ bar を選択します。
!Null非包含アサーション演算子キャストに失敗した場合に実行時例外をスローして、式の基になる非null可能型にキャストします。例: foo!.barfoo が null でないとアサートし、プロパティ bar を選択します。foo が null の場合 (その場合、実行時例外がスローされます)。

.?.、および .. 演算子の詳細については、クラスを参照してください。