Null Sicherheit in Dart

Hallo Habr! Ich mache Sie auf die Übersetzung des Artikels "Announcing Sound Null Safety" von Filip Hracek mit meinen Kommentaren aufmerksam:



Null Safety - sichere Arbeit mit leeren Links. Weiter im Text wird der Kürze halber und aufgrund der Stabilität des Begriffs der englische Name null, null security verwendet. Und die Übersetzung "Null Sicherheit" führt zu völlig entgegengesetzten Gedanken.

Ton - in diesem Zusammenhang (Sound Null Sicherheit) kann als "zuverlässig" übersetzt werden.

Wenn Sie Vorschläge zur Verbesserung der Übersetzung haben oder Fehler gefunden haben - schreiben Sie persönlich, wir werden versuchen, diese zu beheben.
Ein wichtiger Schritt ist für das Dart-Team mit der Präsentation einer technischen Vorschau auf die Null-Sicherheitsentwicklungen gekommen. Die Nullsicherheit vermeidet eine ganze Klasse von Fehlern, die oft schwer zu erkennen sind, und bietet als Bonus eine Reihe von Leistungsverbesserungen. Im Moment haben wir eine vorläufige technische Vorschau veröffentlicht und warten auf Ihr Feedback.



In diesem Artikel werden wir die Pläne des Dart-Teams zur Bereitstellung von Nullsicherheit erläutern und erläutern, was hinter dem Begriff Sound-Nullsicherheit steckt und wie sich dieser Ansatz von anderen Programmiersprachen unterscheidet.

Die beschriebene Version wurde am 10. Juni 2020 vorgestellt.

Warum keine Sicherheit?



Dart ist eine typsichere Sprache. Das heißt, wenn Sie eine Variable eines Typs erhalten, kann der Compiler garantieren, dass sie dazu gehört. Die Typensicherheit allein garantiert jedoch nicht, dass eine Variable nicht null ist.



Nullfehler sind häufig. Eine Suche auf GitHub findet Tausende von Berichten (Problemen), die durch Nullwerte im Dart-Code verursacht wurden, und noch mehr Commits, die versuchen, diese Probleme zu lösen.



Versuchen Sie, das Problem mit dem Nulling-Link im folgenden Beispiel zu erkennen:



void printLengths(List<File> files) {
  for (var file in files) {
    print(file.lengthSync());
  }
}


Diese Funktion wird sicherlich fehlschlagen, wenn sie mit einem Nullparameter aufgerufen wird. Es ist jedoch ein zweiter Fall zu berücksichtigen:



void main() {
  // Error case 1: passing a null to files.
  printLengths(null);
 
  // Error case 2: passing list of files, containing a null item.
  printLengths([File('filename1'), File('filename2'), null]);
}


Null-Sicherheit behebt dieses Problem:



Bild



Mit Null-Sicherheit können Sie sich sicherer auf Ihren Code verlassen. Beim Zugriff auf eine nullfähige Variable zur Laufzeit treten keine störenden Fehler mehr auf. Nur statische Fehler zur Kompilierungszeit.

Um ganz ehrlich zu sein, bietet die aktuelle Implementierung zum Zeitpunkt der Ausführung noch einige Möglichkeiten, Nullfehler abzufangen, dazu später mehr.

Sound (zuverlässig) Null Sicherheit



Darts Implementierung von Nullsicherheit ist solide. Wenn wir es anhand des obigen Beispiels analysieren, bedeutet dies, dass der Dart-Compiler zu 100% sicher ist, dass das Array von Dateien und die darin enthaltenen Elemente nicht null sein können. Wenn der Dart-Compiler Ihren Code analysiert und feststellt, dass die Variable nicht null ist, hat diese Variable immer einen Wert: Wenn Sie Ihren ausführbaren Code im Debugger überprüfen, werden Sie feststellen, dass zur Laufzeit einfach keine Möglichkeit zum Nullstellen besteht. Es gibt nicht "zuverlässige" Implementierungen, die zur Laufzeit noch prüfen müssen, ob ein Wert vorhanden ist. Im Gegensatz zu anderen Sprachen teilt Dart die Implementierungszuverlässigkeit mit Swift.

, , , null safety . Swift, Kotlin Dart. .
Diese robuste Implementierung der Nullsicherheit in Dart hat eine weitere nette Konsequenz: Sie bedeutet, dass Ihre Programme kleiner und schneller sein können. Da Dart wirklich sicherstellt, dass Variablen niemals annulliert werden können, kann Dart das Kompilierungsergebnis optimieren. Beispielsweise kann der AOT-Compiler kleineren und schnelleren nativen Code generieren, da keine Überprüfungen auf leere Referenzen hinzugefügt werden müssen.



Wir haben einige sehr vielversprechende vorläufige Ergebnisse gesehen. Beispielsweise konnten wir bei einem Mikrobenchmark, das typische Rendering-Muster im Flutter-Framework emuliert, eine Leistungsverbesserung von 19% feststellen.



Grundprinzipien



Bevor das Dart-Team mit dem detaillierten Entwurf der



Nullsicherheit fortfuhr, definierte es drei Grundprinzipien: Standardmäßig Nicht-Nullfähigkeit. / ** Dies kann in der Dokumentation häufig als Abkürzung für NNBD angesehen werden. ** / Wenn Sie Dart nicht ausdrücklich mitteilen, dass eine Variable annulliert werden kann, wird sie als nicht nullbar angesehen. Wir haben dies als Standard gewählt, da wir festgestellt haben, dass in der API ein Wert ungleich Null bei weitem am häufigsten vorkommt. / ** Dies ist wahrscheinlich eine Überarbeitung der aktuellen Flutter-API ** / .



Stufenweise Anwendbarkeit... Wir verstehen, dass es die Möglichkeit eines schrittweisen Übergangs zur Nullsicherheit Schritt für Schritt geben muss. Tatsächlich müssen Sie im selben Projekt null- und null-Sicherheitscode haben. Zu diesem Zweck planen wir Tools zur Unterstützung der Codemigration.



Vollständige Zuverlässigkeit (Ton). Wie oben erwähnt, ist die Nullsicherheit in Dart sicher. Sobald Sie Ihr gesamtes Projekt und Ihre Abhängigkeiten auf Nullsicherheit umgestellt haben, erhalten Sie alle Zuverlässigkeitsvorteile.



Variablen mit Nullsicherheit deklarieren



Die grundlegende Syntax ist einfach genug. Unten finden Sie ein Beispiel für die Deklaration verschiedener Variablen. Beachten Sie, dass nicht nullfähige Variablen standardmäßig verwendet werden, sodass sie gleich aussehen, ihr Wert jedoch nicht annulliert werden kann.



// In null-safe Dart, none of these can ever be null.
var i = 42;
final b = Foo();
String m = '';


Dart stellt sicher, dass Sie keiner der oben genannten Variablen null zuweisen. Wenn Sie versuchen, i = null auch tausend Zeilen später auszuführen, erhalten Sie einen statischen Analysefehler und rote, schnörkellose Zeilen - Ihr Programm weigert sich zu kompilieren.



Wenn Ihre Variable nullwertfähig sein soll, können Sie '?' so:



// These are all nullable variables.
int? j = 1;  // Can be null later.
final Foo? c = getFoo();  // Maybe the function returns null.
String? n;  // Is null at first. Can be null at any later time, too


Die oben aufgeführten Variablen verhalten sich genauso wie alle Variablen in der aktuellen Version von Dart.



'?' 'kann auch an anderen Orten verwendet werden:



// In function parameters.
void boogie(int? count) {
  // It's possible that count is null.
}
// In function return values.
Foo? getFoo() {
  // Can return null instead of Foo.
}
// Also: generics, typedefs, type checks, etc.
// And any combination of the above.


Aber ich wünschte, Sie müssten fast nie '?' Verwenden. Die überwiegende Mehrheit Ihrer Variablen ist nicht nullwertfähig.



Erleichtert die Verwendung der Nullsicherheit



Das Dart-Team arbeitet hart daran, die Sicherheit so einfach wie möglich zu gestalten. Schauen Sie sich zum Beispiel diesen Code an, der if verwendet, um auf null zu testen:



void honk(int? loudness) {
  if (loudness == null) {
    // No loudness specified, notify the developer
    // with maximum loudness.
    _playSound('error.wav', volume: 11);
    return;
  }
  // Loudness is non-null, let's just clamp it to acceptable levels.
  _playSound('honk.wav', volume: loudness.clamp(0, 11));
}


Beachten Sie, dass Dart klug genug ist, um zu erkennen, dass die Lautstärke zum Zeitpunkt der Übergabe der if-Anweisung nicht null sein kann. Und so erlaubt uns Dart, die clamp () -Methode aufzurufen, ohne unnötig mit einem Tamburin zu tanzen. Diese Bequemlichkeit bietet die sogenannte Flussanalyse: Der Dart-Parser betrachtet Ihren Code so, als würde er ihn ausführen, und findet automatisch weitere Informationen zu Ihrem Code heraus.

Flow analysis, Dart, , , . null safety, :
foo(dynamic str) {
  if (str is String) {
    // dynamic   length,   
    //      String
    print(str.length);  
  }
}


, Dart , null, :
int sign(int x) {
  // The result is non-nullable.
  int result;
  if (x >= 0) {
    result = 1;
  } else {
    result = -1;
  }
  // By this point, Dart knows the result cannot be null.
  return result;
}


- (, result = -1;), Dart , result — , .
Die Durchflussanalyse funktioniert nur innerhalb von Funktionen. Wenn Sie eine globale Variable oder ein Klassenfeld haben, kann Dart nicht garantieren, dass ihm ein Wert zugewiesen wird. Dart kann den Ausführungsfluss Ihrer gesamten Anwendung nicht simulieren. Aus diesem Grund können Sie das neue Schlüsselwort late verwenden, wenn Sie wissen, dass die Variable beim ersten Zugriff initialisiert wird, Sie sie jedoch nicht initialisieren können, wenn sie deklariert wird.



class Goo {
  late Viscosity v;
 
  Goo(Material m) {
    v = m.computeViscosity();
  }
}


Beachten Sie, dass v nicht auf Null gesetzt werden kann, obwohl es anfangs irrelevant ist. Dart glaubt, dass Sie nicht versuchen werden, v zu lesen, bis ihm ein Wert ungleich Null zugewiesen wurde und Ihr Code fehlerfrei kompiliert wird.

— .



, . , . Dart , , , , , Kotlin .



— Swift- , , force unwrap Dart.

void main() {
  String? t;
  print(t!.length);
}


( late ‘!’) .



late , - Dart. ‘required’ . ‘@required’, .
class Temp {
  String str;
  Temp({required this.str});
  
  //   
  Temp.alt({strAtr}) : this.str = strAtr;
}




Das Dart-Team arbeitet seit über einem Jahr daran, einer technischen Vorschau keine Sicherheit zu geben. Dies ist die größte Sprachänderung seit der Veröffentlichung der zweiten Version. Dies ist jedoch eine Änderung, die die Abwärtskompatibilität nicht beeinträchtigt. Vorhandener Code kann Code mit Nullsicherheit aufrufen und umgekehrt. Auch nach einer vollständigen Version ist die Nullsicherheit eine zusätzliche Option, die Sie verwenden können, wenn Sie bereit sind. Ihr vorhandener Code funktioniert weiterhin unverändert.



Die Kernbibliotheken von Dart wurden kürzlich mit Null-Sicherheit aktualisiert. Als anschauliches Beispiel für die Abwärtskompatibilität wurde der Austausch vorhandener Kernbibliotheken ohne einen einzigen fehlgeschlagenen Test und ohne Fehler in Testanwendungen durchgeführt, die in Dart- und Flutter-Testumgebungen ausgeführt werden. Selbst die Aktualisierung der Kernbibliotheken für viele interne Clients von Google verlief reibungslos. Wir planen, alle unsere Pakete und Anwendungen so zu gestalten, dass nach der Veröffentlichung keine Sicherheit mehr besteht. Wir hoffen, dass Sie dies auch tun. Aber Sie können es in Ihrem eigenen Tempo tun, Batch für Batch, App für App.

Diese Worte, ja, für Swift-Entwickler, insbesondere für die 3. Version ...

Aber selbst hier ist nicht alles so rosig. Die Entwickler selbst sagen, dass sie bei der Kombination von Null-Sicherheitscode und "altem" Code in einem Projekt keine Solidität garantieren können Typ Systeme.

Weiterer Aktionsplan



Wir planen, die Nullsicherheit schrittweise in drei Phasen einzuführen:



  1. Technische Vorschau. Es wurde gestartet, als der Originalartikel veröffentlicht wurde (10.06.2020) und ist in der Dev-Filiale verfügbar. Es lohnt sich, auf den Abschnitt "Jetzt starten" zu achten. Es ist immer noch sehr instabil und kann sich ändern. Wir empfehlen daher, es noch nicht im Produktionscode zu verwenden. Aber wir würden gerne von Ihnen hören und uns Feedback geben!
  2. Betaversion. Null-Sicherheit wird in der Dart-Beta-Filiale verfügbar sein und sich nicht mehr hinter einer experimentellen Flagge verstecken. Die Implementierung wird in der Nähe der erwarteten endgültigen Version sein. Es ist möglich, Ihre Pakete und Plugins auf pub.dev zu migrieren. Es wird jedoch noch nicht empfohlen, diese Änderung als stabile Version zu veröffentlichen.
  3. Stabile Version. Null-Sicherheit steht allen zur Verfügung. Sie werden aufgefordert, Ihre aktualisierten Pakete und Plugins als stabile Versionen zu veröffentlichen. In dieser Phase lohnt es sich auch, Ihre Anwendungen zu migrieren.


Wenn alles nach Plan läuft, werden wir bis Ende des Jahres eine stabile Version von Dart ohne Sicherheit veröffentlichen. Von Zeit zu Zeit werden wir Tools hinzufügen, die Ihnen helfen, auf Null Sicherheit zu kommen. Unter ihnen:



  • Ein Migrationstool zur Automatisierung der zahlreichen Schritte zum Aktualisieren vorhandener Pakete und Anwendungen.
  • pub.dev, null safety;
  • 'pub outdated' , null safety.




Der schnellste Weg, Null-Sicherheit heute zu versuchen, ist mit nullsafety.dartpad.dev - der Version von DartPad mit aktivierter Null-Sicherheit. Öffnen Sie die Dropdown-Liste Lernen mit Snippets, um eine Reihe von Tutorials zu finden, die die neue Syntax und die Grundlagen der Nullsicherheit behandeln.



Bild



Sie können auch in kleinen Konsolenanwendungen mit Nullsicherheit experimentieren (größere Frameworks wie Flutter haben wir noch nicht aktualisiert). Zuerst müssen Sie das Dart SDK aus dem Entwicklungszweig herunterladen, dann können Sie diese Beispielkonsolenanwendung herunterladen . Die README-Datei enthält Anweisungen zum Ausführen der Anwendung mit aktivierter experimenteller Nullsicherheitsfunktion. Die anderen Dateien im Beispiel enthalten Ausführungskonfigurationen, die das Debuggen in VS Code und Android Studio ermöglichen.



Sie können auch die Dokumentation lesen (weitere werden in Zukunft erscheinen):





UPD: In den Kommentaren, schlug ich diesen Link null Sicherheit zu verstehen


Wir freuen uns, Null-Sicherheit in Dart implementieren zu können. Der zuverlässige und sichere Umgang mit leeren Links wird zum Markenzeichen von Dart, damit Sie den zuverlässigsten und produktivsten Code schreiben können. Wir hoffen, dass Sie sich etwas Zeit nehmen, um mit der aktuellen Version von Null Safety zu experimentieren und Ihr Feedback in unserem Bug-Tracker zu hinterlassen. Hab einen schönen Code!

Danke fürs Lesen bis zum Ende. Die Übersetzung ist etwas spät, aber hoffentlich waren die Kommentare für das Material nützlich und es wurde nicht nur eine Eins-zu-Eins-Übersetzung. Ich möchte hinzufügen, dass diese Funktion ein wirklich nützlicher Fortschritt für das gesamte Flutter-Ökosystem ist. Ich freue mich darauf, es bereits in Live-Apps zu verwenden. In der Zwischenzeit, wie es in Fremdsprachen heißt, bleiben Sie dran!



All Articles