Что такое идиома или передовая практика проверки нуля в Dart?

85

У меня есть следующая форма присваивания и нулевых проверок, чтобы избежать двойного поиска на моих картах.
Есть ли лучший или более идиоматический способ сделать это в Dart?

bool isConnected(a, b){
  List list;
  return (
    ((list = outgoing[a]) != null && list.contains(b)) ||
    ((list = incoming[a]) != null && list.contains(b))
  );
}
z5h
источник

Ответы:

120

Начиная с Dart 1.12, для этого типа ситуаций доступны нулевые операторы:

bool isConnected(a, b) {
  bool outConn = outgoing[a]?.contains(b) ?? false;
  bool inConn = incoming[a]?.contains(b) ?? false;
  return outConn || inConn;
}

В ?.операторе короткое замыкание в нуль , если левая сторона имеет нулевое значение, а ??оператор возвращает сторону левой руки , если он не пустой, а правая сторона в противном случае.

Заявление

outgoing[a]?.contains(b)

Таким образом, будет либо оцениваться, nullесли outgoing[a]есть null, либо логический результат, contains(b)если это не так.

Это означает, что результирующий оператор будет одним из следующих:

bool outConn = null ?? false; // false
bool outConn = false ?? false; // false
bool outConn = true ?? false; // true

То же самое относится к inConnлогическому, что означает, что оба inConnи outConnгарантированно не равны нулю, что позволяет нам возвращать результат их обработки ||.

Пиксельный слон
источник
Написание outgoing[a]?.contains(b)опасно, по крайней мере, с семантикой Groovy, потому что когда outgoingесть null, все выражение оценивается как null. Таким образом, вы действительно можете получить что-то вроде return (null || true), которое будет выбрано в проверенном режиме.
Ladicek 09
Спасибо за ссылку на открытый вопрос.
z5h 09
@Ladicek Спасибо, что указали на это. Я включил оператор объединения с нулевым значением ( ??) в свой обновленный ответ, чтобы учесть эту проблему.
Pixel Elephant
2
Наконец-то приземлился \ o / github.com/gbracha/nullAwareOperators/blob/master/proposal.md
Günter Zöchbauer
Чтобы проверить поля объектов, просто напишите object?.field ?? true. Где правда, может быть все, что угодно.
Тило
50

Теперь есть 4 оператора с нулевым значением

?? предоставляет значение по умолчанию, если тема пуста

return subject ?? "defaultIfNull";

?? = устанавливает тему по умолчанию, только если тема пуста

Это похоже на ?? но устанавливает для переменной субъекта значение по умолчанию, если оно равно нулю.

subject ??= "defaultIfNull";

? избегать исключения, если объект имеет значение null при доступе к свойству субъекта

object?.xвернет null, если объект имеет значение null, object.xвызовет исключение, если объект имеет значение null

...? из коллекции распространения, избегайте нулевого элемента в окончательном списке, если список тем пуст

результат следующего

[
  ...[1, 2],
  null,
]

является [1, 2, null]

чтобы избежать использования нулевого значения ...?

var resultingList = [
  ...[1, 2],
  ...?subjectList,
];
Атрион
источник
2
Важное замечание об использовании ?. : если ссылка, допускающая значение NULL, aимеет метод void method(), следующий синтаксис a?.method();выполнит метод, только если aон не равен NULL.
Alex
@AlexSemeniuk, отличный момент! но есть ли способ сделать что-то вроде этого >>> если a не равно нулю ... затем выполнить метод XYZ (), когда этот метод не является членом класса объекта a ???
Yo Apps
@YoApps Я понял, что вы хотите выполнить метод, который не является частью сигнатуры класса? Это невозможно сделать ни на одном из известных мне языков ООП.
Alex Semeniuk
@AlexSemeniuk да, я тоже пробовал, не получилось, так что вернулся к старомуif(a!=null){XYZ();}
Yo Apps
1
@YoApps. О, вы имеете в виду этот код. Нет, в Dart это невозможно.
Alex Semeniuk
15

Публикуя следующее, поскольку я оказался здесь, выполнив поиск по названию.

Согласно https://github.com/dart-lang/sdk/issues/66 , кажется, что это ответ на вопрос «Что такое идиома проверки нуля в Dart или передовая практика?» является:

В общем случае не существует идиомы нулевой проверки или передового опыта. Если операторы с нулевым значением не подходят для вашего случая, используйте прямое сравнение, например if (object == null)или if (object != null).

стан
источник
1
теперь у них есть
Оливер Диксон
0
bool ok<T>(T obj) => obj != null;
bool nul<T>(T obj) => obj == null;
бинарез
источник
Хотя этот код может ответить на вопрос, предоставление дополнительного контекста относительно того, почему и / или как этот код отвечает на вопрос, улучшает его долгосрочную ценность. Как ответить . С уважением.
Elletlar 06