Операторы Dart

Операторы — это символы, которые выполняют вычисления, сравнения и логические проверки в программах.

В этой главе систематически рассматриваются различные операторы в Dart, включая арифметические, реляционные, логические, операторы присваивания, условные операторы и проверку типов.


Арифметические операторы

Арифметические операторы используются для выполнения базовых математических операций

Пример

void main() {
  int a = 10;
  int b = 3;

  print('a = $a, b = $b');
  print('Сложение a + b = ${a + b}');    // 13
  print('Вычитание a - b = ${a - b}');    // 7
  print('Умножение a * b = ${a * b}');    // 30
  print('Деление a / b = ${a / b}');    // 3.333... (результат — double)
  print('Целочисленное деление a ~/ b = ${a ~/ b}');  // 3 (целая часть, дробная отбрасывается)
  print('Остаток от деления a % b = ${a % b}');    // 1 (операция взятия остатка)
  print('Отрицание -a = ${-a}');          // -10 (унарный минус)
}
a = 10, b = 3
加法 a + b = 13
减法 a - b = 7
乘法 a * b = 30
除法 a / b = 3.3333333333333335
整除 a ~/ b = 3
取余 a % b = 1
取反 -a = -10

Примечание: оператор / всегда возвращает тип double, даже если оба операнда int и делятся нацело. Если нужен только целочисленный результат, используйте оператор целочисленного деления ~/.

Операторы инкремента и декремента

Как и большинство языков семейства C, Dart поддерживает ++ (инкремент) и -- (декремент).

Пример

void main() {
  int count = 0;

  // Префиксный ++: сначала инкремент, затем использование
  print('Префиксный ++: ${++count}');  // 1

  // Постфиксный ++: сначала использовать, затем инкремент
  print('Постфиксный ++: ${count++}');  // 1 (на этом этапе count всё ещё равен 1)
  print('Теперь count = $count');   // 2

  // То же самое для декремента
  print('Префиксный --: ${--count}');  // 1
  print('Постфиксный --: ${count--}');  // 1
  print('Теперь count = $count');   // 0
}
前置 ++: 1
后置 ++: 1
现在 count = 2
前置 --: 1
后置 --: 1
现在 count = 0

Префиксный и постфиксный инкремент/декремент дают одинаковый эффект при использовании отдельно, но ведут себя по-разному внутри выражений. Новичкам рекомендуется по возможности избегать их использования в выражениях; запись их на отдельной строке понятнее.


Операторы отношения

Операторы отношения используются для сравнения двух значений, и результатом является значение типа bool.

ОператорыЗначениеПримерРезультат
==equals5 == 5истина
!=Не равно5 != 3истина
>знак больше5 > 3истина
<знак меньше5 < 3false
>=больше или равно5 >= 5истина
<=меньше или равно3 <= 5истина

Пример

void main() {
  int exampleScore = 95;
  int passLine = 60;

  print(Балл: $exampleScore, Проходной балл: $passLine);
  print(Пройдено? ${exampleScore >= passLine});
  print(Максимальный балл? ${exampleScore == 100});

  // Строки тоже можно сравнивать
  String a = 'apple';
  String b = 'banana';
  print("'$a' == '$b'? ${a == b}");

  // == проверяет, равны ли значения
  String c = 'EXAMPLE';
  String d = 'EXAMPLE';
  print("'$c' == '$d'? ${c == d}");  // true (одинаковое содержимое)
}
分数: 95, 及格线: 60
及格了吗? true
满分了吗? false
'apple' == 'banana'? false
'EXAMPLE' == 'EXAMPLE'? true

В Dart == сравнивает, равны ли значения двух объектов, а не их ссылочные адреса. Это отличается от Java — в Dart не нужно использовать метод equals() для сравнения строк.


Логические операторы

Логические операторы используются для объединения нескольких выражений bool, обычно для условных проверок.

ОператорыЗначениеОписание
&&Логическое ИВозвращает true, только если обе стороны истинны.
||Логическое ИЛИВозвращает true, если хотя бы одна сторона истинна.
!Логическое НЕОтрицание: true становится false, false становится true.

Пример

void main() {
  bool isLoggedIn = true;
  bool isAdmin = false;

  // && AND: оба истинны
  print(Вы вошли в систему и являетесь администратором: ${isLoggedIn && isAdmin});  // false

  // || OR: хотя бы одна сторона истинна
  print(Вход выполнен или является администратором: ${isLoggedIn || isAdmin});  // true

  // ! NOT: отрицание
  print(Вход не выполнен: ${!isLoggedIn});  // false

  // Сокращённое вычисление: если левая часть уже определяет результат, правая часть не будет выполняться
  int age = 20;
  // age > 18 уже true, но правую часть тоже нужно проверить
  print(Совершеннолетний и имеет разрешение: ${age >= 18 && isAdmin});

  // age < 18 уже false, поэтому правая часть && пропускается сразу
  print('Несовершеннолетний и имеет разрешение: ${age < 18 && isAdmin}');
}
登录且是管理员: false
登录或是管理员: true
未登录: false
成年且有权限: false
未成年且有权限: false

Dart используетСокращённое вычислениеДля &&, если левая часть false, правая часть не вычисляется; для ||, если левая часть true, правая часть не вычисляется.

Эту возможность можно использовать, чтобы избежать проблем с null-указателями.

Пример

Практические применения сокращённого вычисления:

void main() {
  String? username;

  // Проверка безопасности: username не равен null и длина больше 3
  // Если username равен null, правая часть && не выполнится, что позволит избежать ошибки нулевого указателя
  if (username != null && username.length > 3) {
    print('Корректное имя пользователя');
  } else {
    print('Недопустимое имя пользователя или слишком короткое');
  }
}
Username is invalid or too short.

Операторы присваивания

Вы уже знакомы с базовым оператором присваивания =.

Dart также предоставляет составные операторы присваивания, чтобы упростить типичные операции "вычислить, затем присвоить".

ОператорыЭквивалентный синтаксисПример (когда a=10)
+=a = a + ba += 3 → 13
-=a = a - ba -= 3 → 7
*=a = a * ba *= 3 → 30
/=a = a / ba /= 2 → 5.0
~/=a = a ~/ ba ~/= 3 → 3
%=a = a % ba %= 3 → 1

Пример

void main() {
  int score = 0;

  // Добавить 10 баллов за каждый правильный ответ
  score += 10;
  print('Правильный ответ на вопрос 1: $score');

  score += 10;
  print('Правильный ответ на вопрос 2: $score');

  // Неправильный ответ вычитает 5 баллов
  score -= 5;
  print('Неправильный ответ на 1 вопрос: $score');

  // Удвоить счёт
  score *= 2;
  print('Награда удвоена: $score');

  print('ПРИМЕР итоговый счёт: $score');
}
答对第1题: 10
答对第2题: 20
答错1题: 15
奖励翻倍: 30
EXAMPLE 最终得分: 30

Условные операторы: ?? и ??=

Эти два оператора специально предназначены для обработки значений null и являются важной частью системы null safety в Dart.

?? оператор объединения с null

Если левое выражение не null, вернуть его значение; в противном случае вернуть правое значение.

??= оператор присваивания с учётом null

Если переменная сейчас null, присвоить ей значение справа; в противном случае оставить её без изменений.

Пример

void main() {
  // ?? объединение с null
  String? nickname;
  String displayName = nickname ?? 'EXAMPLE user';
  print(displayName);  // EXAMPLE user

  nickname = 'Little R';
  displayName = nickname ?? 'EXAMPLE user';
  print(displayName);  // Little R

  // Цепочка ?? также работает
  String? a;
  String? b;
  String result = a ?? b ?? 'Default value';
  print(result);  // Default value

  // ??= присваивание с объединением с null
  int? count;
  count ??= 0;  // count равен null, присвоить 0
  print(count);  // 0

  count ??= 100;  // count уже равен 0 (не null), присваивание не требуется
  print(count);  // 0 (без изменений)
}
EXAMPLE 用户
小R
默认值
0
0

Тернарный условный оператор ? :

Это единственный трёхоперандный оператор в Dart, краткая версия if-else.

Пример

void main() {
  int score = 75;

  // Синтаксис: условие ? значение, если истина : значение, если ложь
  String result = score >= 60 ? 'Pass' : 'Fail';
  print('ПРИМЕР результата экзамена: $result');

  // Можно вкладывать (но не рекомендуется превышать два уровня; читаемость ухудшится)
  String grade = score >= 90 ? 'Отлично' : score >= 60 ? 'Сдал' : 'Не сдал';
  print('Оценка: $grade');
}
EXAMPLE 考试结果: 及格
评级: 及格

Операторы проверки типа: is и as

is используется для проверки, принадлежит ли объект типу, as используется для приведения типа.

Пример

void main() {
  // is: проверка типа
  var name = 'EXAMPLE';
  print('Является ли name типом String? ${name is String}');   // true
  print('Является ли name типом int? ${name is int}');         // false

  // is!: не является каким-то типом
  print('Не является ли name типом int? ${name is! int}');      // true

  // as: приведение типа
  Object obj = 'Привет, Dart!';
  // Приведение типа Object к String для использования методов String
  String str = obj as String;
  print(str.toUpperCase());

  // Безопасная проверка типа + преобразование
  Object maybeString = 42;
  if (maybeString is String) {
    // В ветке, где проверка is истинна, переменная автоматически «повышается» до этого типа
    print(maybeString.length);  // Преобразование as не требуется
  } else {
    print('Не строка, значение: $maybeString');
  }
}
name 是 String 吗? true
name 是 int 吗? false
name 不是 int 吗? true
HELLO, DART!
不是字符串,值是: 42

Предпочитайте использовать is для проверки типа. В ветке условия, где is возвращает true, Dart автоматически повышает переменную до целевого типа (Type Promotion), поэтому нет необходимости использовать as для приведения. Используйте as только когда вы уверены в типе, но компилятор не может его вывести.


Обзор приоритета операторов

Когда выражение содержит несколько операторов, Dart вычисляет их в порядке приоритета от высшего к низшему.

Если вы не уверены в приоритете, самая безопасная практика —использовать скобки для уточнения порядка вычислений。

ПриоритетОператорыОписание
Наивысшая() [] . ?.Круглые скобки, индексы, доступ к членам
! ~ - ++ --Унарные операторы
* / % ~/Умножение, деление и остаток
+ -Аддитивные
< <= > >=Сравнение отношений
== !=Проверка равенства
&&Логическое И
||Логическое ИЛИ
??Объединение с null
? :Тернарный условный оператор
= += -= *= и т. д.Присваивание (низший приоритет)

Пример

void main() {
  // Не полагайтесь на приоритет — используйте скобки, чтобы ясно выразить своё намерение.
  int result = ((10 + 5) * 2) - (8 ~/ 3);
  print('Результат вычисления: $result');  // 28

  // Без скобок результат может быть совершенно другим.
  // 10 + 5 * 2 - 8 ~/ 3 будет 18 (умножение и деление перед сложением и вычитанием)
  int result2 = 10 + 5 * 2 - 8 ~/ 3;
  print('Без скобок: $result2');  // 18
}
计算结果: 28
不加括号: 18
Другие расширения