目次

演算子

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
カスケード..    ?..
代入=    *=    /=   +=   -=   &=   ^=   など
スプレッド (注を参照)...    ...?なし

演算子を使用すると、式が作成されます。演算子式の例をいくつか示します。

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. 引数yx==メソッドを呼び出した結果を返します。(そうです、==などの演算子は、最初のオペランドで呼び出されるメソッドです。詳細については、演算子を参照してください。)

等値および関係演算子のそれぞれを使用する例を次に示します。

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

型テスト演算子

#

asisis!演算子は、実行時に型をチェックするのに便利です。

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

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

オブジェクトが型Tであると確信している場合にのみ、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をテストする場合は、if-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
querySelector('#confirm') // Get an object.
  ?..text = 'Confirm' // Use its members.
  ..classes.add('important')
  ..onClick.listen((e) => window.alert('Confirmed!'))
  ..scrollIntoView();

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

dart
var button = querySelector('#confirm');
button?.text = 'Confirm';
button?.classes.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の要素にアクセスするために、int1fooListに渡します。
?[]条件付き添字アクセス[]に似ていますが、左側のオペランドはnullになる可能性があります。例:fooList?[1]は、fooListがnullでない限り(その場合は式はnullになります)、インデックス1の要素にアクセスするためにint1fooListに渡します。
.メンバアクセス式のプロパティを参照します。例:foo.barは、式fooからプロパティbarを選択します。
?.条件付きメンバアクセス.に似ていますが、左側のオペランドはnullになる可能性があります。例:foo?.barは、fooがnullでない限り(その場合はfoo?.barの値はnullになります)、式fooからプロパティbarを選択します。
!非nullアサーション演算子式を基になる非null型にキャストし、キャストに失敗した場合はランタイム例外をスローします。例:foo!.barは、fooがnullでないことをアサートし、プロパティbarを選択します。fooがnullの場合はランタイム例外がスローされます。

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