Операторы
Dart определяет операторы, показанные в следующей таблице. Вы можете переопределить многие из этих операторов, как описано в разделе «Переопределяемые операторы».
Описание | Оператор |
одинарный постфикс | expr++ expr-- () [] ?[] . ?. ! |
одинарный префикс |
|
мультипликативный | / % ~/ |
адитивный | + - |
сдвиг | << >> >>> |
побитовое И | & |
побитовый XOR | ^ |
побитовое ИЛИ | | |
реляционное и испытание типа | = > <= < as is is! |
равенство | == != |
логическое И | && |
логическое ИЛИ | || |
если null | ?? |
условный | expr1 ? expr2 : expr3 |
каскад | .. ?.. |
назначение | = *= /= += -= &= ^= и т.д. |
Когда вы используете операторы, вы создаете выражения. Вот несколько примеров выражений операторов:
a++
a + b
a = b
a == b
c ? a : b
a is T
В таблице операторов каждый оператор имеет более высокий приоритет, чем операторы в строках, следующих за ним. Например, мультипликативный оператор %
имеет более высокий приоритет, чем (и, следовательно, выполняется раньше) оператор равенства ==
, который имеет более высокий приоритет, чем логический оператор AND &&
. Этот приоритет означает, что следующие две строки кода выполняются одинаково:
// Parentheses improve readability.
if ((n % i == 0) && (d % i == 0)) ...
// Harder to read, but equivalent.
if (n % i == 0 && d % i == 0) ...
Vector
и объект Point
, aVector + aPoint
использует версию Vector
вектора +
.Арифметические операторы
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 ) |
Пример:
var a, 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
Равенство и реляционные операторы
В следующей таблице перечислены значения равенства и реляционных операторов.
Оператор | Значение |
---|---|
== | равное, см. обсуждение ниже |
!= | не равный |
> | больше, чем |
< | меньше, чем |
>= | больше, чем или равно |
<= | меньше, чем или равно |
Чтобы проверить, представляют ли два объекта x
и y
одно и то же, используйте оператор ==
. (В редком случае, когда вам нужно знать, являются ли два объекта одним и тем же объектом, используйте вместо него функцию identifier()
.) Вот как работает оператор ==
:
- Если
x
или y равенnull
, вернитеtrue
, если оба имеют значениеnull
, иfalse
, если только один равен нулю. - Возвращает результат вызова метода
==
дляx
с аргументомy
. (Правильно, такие операторы, как ==, являются методами, которые вызываются для их первого операнда. Подробнее см. в разделе Операторы.)
Вот пример использования каждого из операторов равенства и отношений:
assert(2 == 2);
assert(2 != 3);
assert(3 > 2);
assert(2 < 3);
assert(3 >= 3);
assert(2 <= 3);
Тип тестовых операторов
Как as
, is
, и is!
Операторы удобны для проверки типов во время выполнения.
Оператор | Значение |
as | Typecast (также используется для указания префиксов библиотеки) |
is | True, если объект имеет указанный тип |
is! | False, если объект имеет указанный тип |
Результатом obj is T
— true
, если obj
реализует интерфейс, указанный в T
. Например, obj is Object
— всегда true
.
Используйте оператор as
для приведения объекта к определенному типу. В общем, вы должны использовать его как сокращение для теста is для объекта, за которым следует выражение, использующее этот объект. Например, рассмотрим следующий код:
if (emp is Person) {
// Type check
emp.firstName = 'Bob';
}
Вы можете сделать код короче, используя оператор as
:
(emp as Person).firstName = 'Bob';
emp
является нулем или не Person
, первый пример (с is
) ничего не делает; вторая (с as
) выдает исключение. Операторы присваивания
Как вы уже видели, вы можете присваивать значения с помощью оператора =
. Чтобы назначить, только если переменная назначенного значения пуста, используйте оператор ??=
.
// 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 | инвертирует следующее выражение (изменяет ложь на истину и наоборот) |
|| | логическое ИЛИ |
&& | логическое И |
Вот пример использования логических операторов:
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
Условные выражения
В Dart есть два оператора, которые позволяют вам кратко оценить выражения, для которых в противном случае могут потребоваться операторы if-else
:
условие ? expr1: expr2
Если условие истинно, вычисляет expr1
(и возвращает его значение); в противном случае вычисляет и возвращает значение expr2
.
expr1 ?? expr2
Если expr1
не равен NULL
, возвращает его значение; в противном случае вычисляет и возвращает значение expr2
.
Когда вам нужно присвоить значение на основе логического выражения, рассмотрите возможность использования ?
:
var visibility = isPublic ? 'public' : 'private';
Если логическое выражение проверяет наличие нуля, рассмотрите возможность использования ??
String playerName(String name) => name ?? 'Guest';
Предыдущий пример мог быть написан как минимум двумя другими способами, но не так кратко:
// 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';
}
}
</
Каскадная запись (..)
Каскады (..
) позволяют выполнять последовательность операций над одним и тем же объектом. В дополнение к вызовам функций вы также можете получить доступ к полям этого же объекта. Это часто избавляет вас от необходимости создавать временную переменную и позволяет писать более гибкий код.
Рассмотрим следующий код:
querySelector('#confirm') // Get an object.
..text = 'Confirm' // Use its members.
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed!'));
Первый вызов метода querySelector()
возвращает объект селектора. Код, который следует за каскадной нотацией, работает с этим объектом селектора, игнорируя любые последующие значения, которые могут быть возвращены.
Предыдущий пример эквивалентен:
var button = querySelector('#confirm');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));
Вы также можете вкладывать свои каскады. Например:
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
.
Другие операторы
Вы видели большинство оставшихся операторов в других примерах:
Оператор | Имя | Значение |
( ) | Применение функции | Представляет вызов функции |
[ ] | Доступ к списку | Относится к значению по указанному индексу в списке |
. | Доступ к свойству | Относится к свойству выражения. Пример: foo.bar выбирает bar свойство из выражения foo |
?. | Условный доступ к свойству | Как и . , Но самый левый операнд может быть нулевым. Пример: foo? .bar выбирает bar свойство из выражения foo, если foo не равно нулю (в этом случае значение foo? .bar равно нулю) |
Для получения дополнительной информации об операторах .
, ?.
И ..
см. Классы.