Sécurité nulle dans Dart

Bonjour, Habr! Je présente à votre attention la traduction de l'article "Announcing sound null safety" de Filip Hracek avec mes commentaires:



Null safety - safe work with empty links. Plus loin dans le texte, par souci de concision et en raison de la stabilité du terme, le nom anglais null, null safety sera utilisé. Et la traduction «sécurité zéro» conduit à des pensées complÚtement opposées.

son - dans ce contexte (sĂ©curitĂ© nulle sonore) peut ĂȘtre traduit par «fiable».

Si vous avez des suggestions pour améliorer la traduction ou si vous avez trouvé des erreurs - écrivez-nous, nous essaierons de les corriger.
Une étape importante est venue pour l'équipe de Dart avec la présentation d'un aperçu technique des développements de sécurité nuls. La sécurité nulle évite toute une classe de bogues souvent difficiles à détecter, et en prime, elle apporte un certain nombre d'améliorations de performances. Pour le moment, nous avons publié un aperçu technique préliminaire et attendons vos commentaires.



Dans cet article, nous révélerons les plans de l'équipe Dart pour déployer la sécurité nulle, ainsi que ce qui se cache derriÚre le terme Sound null safety, et en quoi cette approche diffÚre des autres langages de programmation.

La version décrite a été présentée le 10 juin 2020.

Pourquoi une sécurité nulle?



Dart est un langage de type sécurisé. Cela signifie que lorsque vous obtenez une variable d'un certain type, le compilateur peut garantir qu'elle lui appartient. Mais la sécurité de type seule ne garantit pas qu'une variable n'est pas nulle.



Les erreurs nulles sont courantes. Une recherche sur GitHub trouve des milliers de rapports (problÚmes) causés par des valeurs nulles dans le code Dart, et encore plus de commits essayant de résoudre ces problÚmes.



Essayez de repérer le problÚme du lien d'annulation dans l'exemple suivant:



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


Cette fonction échouera certainement si elle est appelée avec un paramÚtre mis à zéro, mais il y a un deuxiÚme cas à considérer:



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]);
}


La sécurité nulle résout ce problÚme:



image



avec la sécurité nulle, vous pouvez compter sur votre code avec plus de confiance. Il n'y aura plus d'erreurs ennuyeuses lors de l'accÚs à une variable annulée lors de l'exécution. Seulement des erreurs statiques au moment de la compilation.

Pour ĂȘtre tout Ă  fait honnĂȘte, l'implĂ©mentation actuelle laisse encore plusieurs opportunitĂ©s pour attraper des erreurs nulles au moment de l'exĂ©cution, plus sur elles plus tard.

Sûreté (fiable) nulle



La mise en Ɠuvre par Dart de la sĂ©curitĂ© nulle est solide. Si nous l'analysons Ă  l'aide de l'exemple ci-dessus, cela signifie que le compilateur Dart est sĂ»r Ă  100% que le tableau de fichiers et les Ă©lĂ©ments qu'il contient ne peuvent pas ĂȘtre nuls. Lorsque le compilateur Dart analyse votre code et dĂ©termine qu'une variable n'est pas nulle, alors cette variable aura toujours une valeur: si vous vĂ©rifiez votre code exĂ©cutable dans le dĂ©bogueur, vous verrez qu'il n'y a tout simplement aucune possibilitĂ© de remise Ă  zĂ©ro au moment de l'exĂ©cution. Il existe des implĂ©mentations non "fiables" dans lesquelles vous devez encore effectuer des vĂ©rifications pour l'existence d'une valeur au moment de l'exĂ©cution. Contrairement Ă  d'autres langages, Dart partage la fiabilitĂ© de l'implĂ©mentation avec Swift.

, , , null safety . Swift, Kotlin Dart. .
Cette implĂ©mentation robuste de la sĂ©curitĂ© nulle dans Dart a une autre consĂ©quence intĂ©ressante: cela signifie que vos programmes peuvent ĂȘtre plus petits et plus rapides. Puisque Dart s'assure vraiment que les variables ne peuvent jamais ĂȘtre annulĂ©es, Dart peut optimiser le rĂ©sultat de la compilation. Par exemple, le compilateur AOT peut gĂ©nĂ©rer du code natif plus petit et plus rapide car il n'a pas besoin d'ajouter des vĂ©rifications pour les rĂ©fĂ©rences vides.



Nous avons vu des résultats préliminaires trÚs prometteurs. Par exemple, nous avons constaté une amélioration des performances de 19% dans un microbenchmark qui émule des modÚles de rendu typiques dans le cadre Flutter.



Principes de base



Avant de procéder à la conception détaillée de la sécurité nulle, l'équipe Dart a défini trois principes de base:



Non-nullabilitĂ© par dĂ©faut. / ** Ceci peut souvent ĂȘtre vu comme une abrĂ©viation de NNBD dans la documentation ** / Si vous ne dites pas explicitement Ă  Dart qu'une variable peut ĂȘtre annulĂ©e, il la considĂ©rera comme non nullable. Nous avons choisi cela par dĂ©faut car nous avons constatĂ© que dans l'API, une valeur diffĂ©rente de zĂ©ro est de loin la plus courante. / ** Il s'agit probablement d'une refonte de l'API Flutter actuelle ** / .



ApplicabilitĂ© par Ă©tapes... Nous comprenons qu'il doit y avoir une possibilitĂ© d'une transition progressive vers la sĂ©curitĂ© nulle Ă©tape par Ă©tape. En fait, vous devez avoir du code de sĂ©curitĂ© nullable et null dans le mĂȘme projet. Pour cela, nous prĂ©voyons de fournir des outils d'aide Ă  la migration de code.



Fiabilité totale (son). Comme mentionné ci-dessus, la sécurité nulle dans Dart est sûre. Une fois que vous avez converti l'ensemble de votre projet et vos dépendances en sécurité nulle, vous bénéficiez de tous les avantages en termes de fiabilité.



Déclaration de variables avec sécurité nulle



La syntaxe de base est assez simple. Voici un exemple de dĂ©claration de diverses variables. Notez que les variables non nulles sont utilisĂ©es par dĂ©faut, elles se ressemblent donc, mais leur valeur ne peut pas ĂȘtre annulĂ©e.



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


Dart s'assurera que vous n'assignez jamais null Ă  l'une des variables ci-dessus. Si vous essayez d'exĂ©cuter i = null mĂȘme mille lignes plus tard, vous obtiendrez une erreur d'analyse statique et des lignes ondulĂ©es rouges - votre programme refusera de compiler.



Si vous voulez que votre variable soit nullable, vous pouvez utiliser '?' comme ça:



// 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


Les variables rĂ©pertoriĂ©es ci-dessus se comportent exactement de la mĂȘme maniĂšre que toutes les variables de la version actuelle de Dart.



'?' 'peut Ă©galement ĂȘtre utilisĂ© dans d'autres endroits:



// 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.


Mais encore une fois, je souhaite que vous n'ayez presque jamais à utiliser «?». La grande majorité de vos variables ne sera pas Nullable.



Faciliter l'utilisation de la sécurité nulle



L'Ă©quipe Dart travaille dur pour rendre la sĂ©curitĂ© nulle aussi facile Ă  utiliser que possible. Par exemple, jetez un Ɠil Ă  ce code, qui utilise if pour tester null:



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));
}


Notez que Dart est suffisamment intelligent pour se rendre compte que le son ne peut pas ĂȘtre nul au moment oĂč nous passons l'instruction if. Et donc Dart nous permet d'appeler la mĂ©thode clamp () sans danser inutile avec un tambourin. Cette commoditĂ© est fournie par l'analyse dite de flux: l'analyseur Dart regarde votre code comme s'il l'exĂ©cutait, trouvant automatiquement plus d'informations sur votre code.

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 — , .
L'analyse de flux ne fonctionne qu'à l'intérieur des fonctions. Si vous avez une variable globale ou un champ de classe, Dart ne peut pas garantir qu'une valeur lui sera affectée. Dart ne peut pas simuler le flux d'exécution de l'ensemble de votre application. Pour cette raison, vous pouvez utiliser le nouveau mot-clé late si vous savez que la variable sera initialisée lors de son premier accÚs, mais vous ne pouvez pas l'initialiser lors de sa déclaration.



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


Notez que v ne peut pas ĂȘtre remis Ă  zĂ©ro, bien qu'au dĂ©part, il ne soit pas pertinent. Dart pense que vous n'essaierez pas de lire v tant qu'il ne lui sera pas attribuĂ© une valeur diffĂ©rente de zĂ©ro et que votre code se compilera sans erreur.

— .



, . , . 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;
}




L'Ă©quipe Dart travaille depuis plus d'un an pour apporter la sĂ©curitĂ© nulle Ă  un aperçu technique. Il s'agit du plus grand changement de langue depuis la sortie de la deuxiĂšme version. Cependant, il s'agit d'un changement qui ne rompt pas la compatibilitĂ© descendante. Le code existant peut appeler du code avec une sĂ©curitĂ© nulle et vice versa. MĂȘme aprĂšs une version complĂšte, la sĂ©curitĂ© nulle sera une option supplĂ©mentaire que vous pourrez utiliser lorsque vous serez prĂȘt. Votre code existant continuera Ă  fonctionner sans changement.



Les bibliothĂšques de base de Dart ont Ă©tĂ© rĂ©cemment mises Ă  jour avec une sĂ©curitĂ© nulle. À titre d'exemple illustratif de compatibilitĂ© descendante, le remplacement des bibliothĂšques de base existantes s'est dĂ©roulĂ© sans Ă©chec d'un seul test et sans erreurs dans les applications de test exĂ©cutĂ©es sur des environnements de test Dart et Flutter. MĂȘme la mise Ă  jour des bibliothĂšques de base pour de nombreux clients internes de Google s'est dĂ©roulĂ©e sans accroc. Nous prĂ©voyons de repenser tous nos packages et applications pour utiliser la sĂ©curitĂ© nulle aprĂšs la publication, nous espĂ©rons que vous ferez de mĂȘme. Mais vous pouvez le faire Ă  votre rythme, lot par lot, application par application.

Ces mots, oui aux développeurs Swift, en particulier à la 3Úme version ...

Mais mĂȘme ici, tout n'est pas si rose, les dĂ©veloppeurs eux-mĂȘmes disent qu'en combinant un code de sĂ©curitĂ© nul et un code "ancien" dans un projet, ils ne peuvent pas garantir la soliditĂ© systĂšmes de type.

Plan d'action supplémentaire



Nous prévoyons de déployer progressivement la sécurité nulle en trois phases:



  1. Aperçu technique. Il a Ă©tĂ© lancĂ© lors de la publication de l'article original (06/10/2020) et est disponible sur la dev-branch. Il convient de prĂȘter attention Ă  la section "Commencer maintenant". Il est encore trĂšs instable et sujet Ă  changement, nous ne recommandons donc pas encore de l'utiliser dans le code de production. Mais nous serions ravis de vous entendre et de nous faire part de vos commentaires!
  2. Version bĂȘta. La sĂ©curitĂ© nulle sera disponible sur la branche bĂȘta de Dart et ne se cachera plus derriĂšre un drapeau expĂ©rimental. La mise en Ɠuvre sera proche de la version finale attendue. Il sera possible de commencer Ă  migrer vos packages et plugins vers pub.dev, mais il n'est pas encore recommandĂ© de publier ce changement en tant que version stable.
  3. Version stable. La sécurité nulle sera accessible à tous. Vous serez invité à publier vos packages et plugins mis à jour en tant que versions stables. Cela vaut également la peine de migrer vos applications à ce stade.


Si tout se passe comme prévu, nous publierons une version stable de Dart avec une sécurité nulle d'ici la fin de l'année. De temps en temps, nous ajouterons des outils pour vous aider à passer à la sécurité nulle. Parmi eux:



  • Un outil de migration pour aider Ă  automatiser les nombreuses Ă©tapes de mise Ă  jour des packages et applications existants;
  • pub.dev, null safety;
  • 'pub outdated' , null safety.




Le moyen le plus rapide d'essayer la sécurité nulle aujourd'hui est d'utiliser nullsafety.dartpad.dev - la version de DartPad avec la sécurité nulle activée. Ouvrez la liste déroulante Apprendre avec des extraits pour trouver une série de didacticiels couvrant la nouvelle syntaxe et les bases de la sécurité null.



image



Vous pouvez également expérimenter la sécurité nulle dans les petites applications de console (nous n'avons pas encore mis à jour des frameworks plus grands comme Flutter). Tout d'abord, vous devez télécharger le SDK Dart à partir de la branche dev, puis vous pouvez télécharger cet exemple d'application console . Le fichier README contient des instructions pour exécuter l'application avec la fonction de sécurité nulle expérimentale activée. Les autres fichiers de l'exemple fournissent des configurations d'exécution qui permettront le débogage dans VS Code et Android Studio.



Vous pouvez Ă©galement lire la documentation (d'autres paraĂźtront dans le futur):





UPD: Dans les commentaires, j'ai suggéré ce lien Comprendre la sécurité nulle


Nous sommes trÚs heureux de pouvoir implémenter la sécurité nulle dans Dart. La gestion fiable et sécurisée des liens vides deviendra la marque de fabrique de Dart pour vous aider à écrire le code le plus fiable et le plus productif. Nous espérons que vous prendrez le temps d'expérimenter la version actuelle de null safety et de laisser vos commentaires dans notre outil de suivi des bogues. Avoir un bon code!

Merci d'avoir lu jusqu'au bout. La traduction était un peu tardive, mais j'espÚre que les commentaires ont été utiles au matériel et qu'il ne s'agit pas simplement d'une traduction individuelle. Je tiens à ajouter que cette fonctionnalité est un pas en avant vraiment utile pour l'ensemble de l'écosystÚme Flutter. J'ai hùte de l'utiliser déjà sur des applications en direct. En attendant, comme on dit en langue étrangÚre, restez à l'écoute!



All Articles