Co to jest idiom lub najlepsza praktyka sprawdzania wartości zerowej w Dart?

84

Mam następującą formę przydziałów i kontroli null, aby uniknąć podwójnego wyszukiwania na moich mapach.
Czy istnieje lepszy lub bardziej idiomatyczny sposób na zrobienie tego w Dart?

bool isConnected(a, b){
  List list;
  return (
    ((list = outgoing[a]) != null && list.contains(b)) ||
    ((list = incoming[a]) != null && list.contains(b))
  );
}
z5h
źródło

Odpowiedzi:

119

Od wersji Dart 1.12 operatory obsługujące wartość null są dostępne dla tego typu sytuacji:

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

Do ?.zwarcia operatorowi NULL jeżeli po lewej stronie jest null, a ??operator zwraca lewej strony, jeśli to nie jest zerowa, a po prawej stronie inaczej.

Twierdzenie

outgoing[a]?.contains(b)

w ten sposób oszacuje, nullczy outgoing[a]jest null, lub jako wynik boolowski, contains(b)jeśli tak nie jest.

Oznacza to, że wynikowa instrukcja będzie jedną z następujących:

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

To samo dotyczy wartości inConnlogicznej, co oznacza, że ​​oba inConni outConnmają gwarantowaną wartość różną od zera, co pozwala nam zwrócić wynik ||tych dwóch.

Pixel Elephant
źródło
Pisanie outgoing[a]?.contains(b)jest niebezpieczne, przynajmniej w przypadku semantyki Groovy'ego, ponieważ kiedy outgoingjest null, całe wyrażenie ocenia się do null. Więc w rzeczywistości możesz dostać coś takiego return (null || true), co wrzuci tryb zaznaczenia.
Ladicek
Dzięki za link do otwartego wydania.
z5h
@Ladicek Dzięki za zwrócenie uwagi. ??Do mojej zaktualizowanej odpowiedzi włączyłem operator łączenia zerowego ( ), aby uwzględnić ten problem.
Pixel Elephant
2
Wreszcie wylądował \ o / github.com/gbracha/nullAwareOperators/blob/master/proposal.md
Günter Zöchbauer
Aby sprawdzić pola obiektów, po prostu napisz object?.field ?? true. Gdzie prawda może być czymkolwiek zechcesz.
Tilo
50

Istnieją teraz 4 operatory świadome wartości zerowej

?? zapewnia wartość domyślną, jeśli temat ma wartość null

return subject ?? "defaultIfNull";

?? = ustawia temat na domyślny tylko wtedy, gdy jest on pusty

To jest podobne do ?? ale ustawia zmienną podmiotu na wartość domyślną, jeśli jest pusta.

subject ??= "defaultIfNull";

? unikaj wyjątku, jeśli podmiot jest pusty podczas uzyskiwania dostępu do właściwości podmiotu

object?.x zwróci wartość null, jeśli obiekt ma wartość null, object.x spowoduje wyjątek, jeśli obiekt będzie miał wartość null

...? z kolekcji rozłożonych, unikaj pustego elementu na ostatecznej liście, jeśli lista tematów jest pusta

wynik następujących czynności

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

jest [1, 2, null]

aby uniknąć wartości null użyj ...?

var resultingList = [
  ...[1, 2],
  ...?subjectList,
];
atreeon
źródło
2
Ważna uwaga na temat używania ? : jeśli odwołanie dopuszczające wartość null ama metodę void method(), następująca składnia a?.method();wykona metodę tylko wtedy, gdy anie jest null.
Alex Semeniuk
@AlexSemeniuk, świetna uwaga! ale czy jest jakiś sposób na zrobienie czegoś takiego >>> jeśli a nie jest null ... wtedy wykonaj metodę XYZ (), gdy ta metoda nie należy do klasy obiektu a ???
Yo Apps
@YoApps Czy zrozumiałem, że chcesz wykonać metodę, która nie jest częścią podpisu klasy? Nie można tego zrobić w żadnym znanym mi języku OOP.
Alex Semeniuk
@AlexSemeniuk tak, też próbowałem, nie działało, więc wróciłem do staregoif(a!=null){XYZ();}
Yo Apps
1
@YoApps. Och, masz na myśli ten kod. Nie, w Dart nie jest to możliwe.
Alex Semeniuk
15

Publikując następujące polecenie, ponieważ znalazłem się tutaj, szukając tytułu.

Jak na https://github.com/dart-lang/sdk/issues/66 , wydaje się, że odpowiedź na pytanie „Co to jest idiom lub najlepsza praktyka sprawdzania wartości zerowej Dart?” jest:

W ogólnym przypadku nie ma idiomu sprawdzania wartości zerowej ani najlepszych praktyk. Jeśli operatory obsługujące wartość null nie pasują do twojego przypadku, użyj bezpośredniego porównania, jak w if (object == null)lub if (object != null).

stanm
źródło
1
teraz mają opcje :-)
Oliver Dixon
0
bool ok<T>(T obj) => obj != null;
bool nul<T>(T obj) => obj == null;
binarez
źródło
Chociaż ten kod może odpowiedzieć na pytanie, zapewnia dodatkowy kontekst dotyczący tego, dlaczego i / lub jak ten kod odpowiada, poprawia jego długoterminową wartość. Jak odpowiedzieć . Z poważaniem.
Elletlar