Was ist die Dart-Nullprüfungssprache oder die beste Vorgehensweise?


82

Ich habe die folgende Form der Zuweisung und Nullprüfung, um doppelte Suchvorgänge in meinen Karten zu vermeiden.
Gibt es eine bessere oder idiomatischere Möglichkeit, dies in Dart zu tun?

bool isConnected(a, b){
  List list;
  return (
    ((list = outgoing[a]) != null && list.contains(b)) ||
    ((list = incoming[a]) != null && list.contains(b))
  );
}

Antworten:


116

Ab Dart 1.12 sind nullbewusste Operatoren für diese Art von Situation verfügbar:

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

Der ?.Operator schließt auf Null kurz, wenn die linke Seite Null ist, und der ??Operator gibt die linke Seite zurück, wenn sie nicht Null ist, und die rechte Seite ansonsten.

Die Aussage

outgoing[a]?.contains(b)

wird also entweder bewerten, nullob es outgoing[a]ist null, oder das boolesche Ergebnis, contains(b)wenn es nicht ist.

Das bedeutet, dass die resultierende Aussage eine der folgenden ist:

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

Gleiches gilt für den inConnBooleschen Wert, der beides bedeutet inConnund outConngarantiert nicht null ist, sodass wir das Ergebnis ||der beiden zurückgeben können.


Schreiben outgoing[a]?.contains(b)ist gefährlich, zumindest bei der Groovy-Semantik, denn wenn dies der Fall outgoingist null, wird der gesamte Ausdruck ausgewertet null. Sie könnten also tatsächlich so etwas bekommen return (null || true), was im aktivierten Modus ausgelöst wird.
Ladicek

Vielen Dank für den Link zur offenen Ausgabe.
z5h

@Ladicek Danke, dass du darauf hingewiesen hast. Ich habe den Null-Coalescing-Operator ( ??) in meine aktualisierte Antwort aufgenommen, um dieses Problem zu berücksichtigen.
Pixel Elephant


Um Felder von Objekten zu überprüfen, schreiben Sie einfach object?.field ?? true. Wo wahr kann alles sein, was Sie wollen.
Tilo

42

Es gibt jetzt 4 nullbewusste Operatoren

?? Gibt eine Standardeinstellung an, wenn der Betreff null ist

return subject ?? "defaultIfNull";

?? = setzt den Betreff nur dann auf einen Standardwert, wenn der Betreff null ist

Das ist ähnlich wie ?? Setzt die Betreffvariable jedoch auf einen Standardwert, wenn sie null ist.

subject ??= "defaultIfNull";

?. Vermeiden Sie eine Ausnahme, wenn der Betreff beim Zugriff auf die Eigenschaft des Betreffs null ist

object?.xgibt null zurück, wenn das Objekt null ist, object.xwürde eine Ausnahme verursachen, wenn das Objekt null wäre

...? Vermeiden Sie aus einer Spread-Sammlung ein Nullelement in der endgültigen Liste, wenn die Betreffliste null ist

das Ergebnis der folgenden

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

ist [1, 2, null]

Um den Nullwert zu vermeiden, verwenden Sie ...?

var resultingList = [
  ...[1, 2],
  ...?subjectList,
];

2
Wichtige Bemerkung zur Verwendung von ?. : Wenn die nullfähige Referenz adie void-Methode hat method(), führt die folgende Syntax a?.method();die Methode nur aus, wenn sie anicht null ist.
Alex Semeniuk

@ AlexSemeniuk, toller Punkt! Aber gibt es eine Möglichkeit, so etwas zu tun >>> wenn a nicht null ist ... dann führe eine Methode XYZ () aus, wenn diese Methode kein Mitglied der Klasse des Objekts a ist ???
Yo Apps

@YoApps Habe ich klargestellt, dass Sie eine Methode ausführen möchten, die nicht Teil der Klassensignatur ist? Es ist nicht möglich, in einer mir bekannten OOP-Sprache zu arbeiten.
Alex Semeniuk

@AlexSemeniuk Ja, ich habe es auch versucht, es hat nicht funktioniert, also bin ich zurück zum altenif(a!=null){XYZ();}
Yo Apps

1
@ YoApps. Oh, du meinst diesen Code. Nein, das ist in Dart nicht möglich.
Alex Semeniuk

14

Folgendes posten, da ich hier gelandet bin, indem ich den Titel gesucht habe.

Gemäß https://github.com/dart-lang/sdk/issues/66 scheint die Antwort auf "Was ist die Dart-Nullprüfungssprache oder die beste Vorgehensweise?" ist:

Im allgemeinen Fall gibt es keine Nullprüfungssprache oder Best Practice. Wenn nullbewusste Operatoren nicht zu Ihrem Fall passen, verwenden Sie einen direkten Vergleich wie in if (object == null)oder if (object != null).


1
Sie haben jetzt Optionen :-)
Oliver Dixon

0
bool ok<T>(T obj) => obj != null;
bool nul<T>(T obj) => obj == null;

Während dieser Code die Frage möglicherweise beantwortet, verbessert die Bereitstellung eines zusätzlichen Kontexts darüber, warum und / oder wie dieser Code die Frage beantwortet, ihren langfristigen Wert. Wie man antwortet . Mit freundlichen Grüßen.
Elletlar
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.