FAQ DartConsultez toutes les FAQ
Nombre d'auteurs : 6, nombre de questions : 85, dernière mise à jour : 29 août 2016 Ajouter une question
Cette FAQ a été réalisée essentiellement à partir de la traduction de la FAQ officielle Dart.
Nous tenons à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes. Les auteurs et traducteurs font leur maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être complète. Si vous trouvez une erreur, ou que vous souhaitez nous aider en devenant rédacteur, lisez ceci.
Je tiens à remercier l'ensemble de l'équipe des rédacteurs de www.developpez.com pour leurs remarques constructives. Ainsi que Lana.Bauer pour son implication dans la mise en ligne de cette FAQ.
Tous deux, nous désirons également remercier Mishulyna, Kenaryn et rawsrc pour leurs traductions, mais aussi BakSh0 pour sa relecture et son aide à la mise en ligne de la FAQ. Merci à Zoom61 pour la création du logo. Finalement, nous remercions jpcheck pour sa relecture orthographique.
Sur ce, nous vous souhaitons une bonne lecture.
N’hésitez pas nous faire part de vos remarques sur le contenu de cette FAQ ou à nous faire vos propositions de contribution !
La rédaction Developpez.com.
- Dart est-il semblable à JavaScript ?
- Dart est-il semblable à Java ?
- Comment comparer Dart avec l'utilisation du compilateur Closure en JavaScript ?
- Comment comparer Dart avec CoffeeScript ?
- Qu'est-ce que Google pense de TypeScript ?
- Dart a-t-il un lien avec Go ?
- Pourquoi Dart ne ressemble-t-il pas plus à Haskell / Smalltalk / Python / Scala / autre langage ?
- Pourquoi la syntaxe de Dart n'est-elle pas plus excitante ?
- Est-il vraiment un langage dynamique s'il n'a pas eval() ou l'ajout de champs à une valeur au moment de l'exécution ?
- Est-ce que Dart possède des possibilités de réflexion ?
- Dart peut-il prendre en compte les tuples, le pattern matching, les types non nullables, l'évaluation partielle, les points-virgules optionnels... ?
- Comment récupérer la sélection de l'utilisateur en Dart ?
- Comment créer une Map avec Dart ?
- Comment gérer les erreurs avec Dart ?
- Comment utiliser les fonctions de callback ?
- Comment créer un cookie avec Dart ?
- Peut-on utiliser les interfaces comme en Java, avec Dart ?
- Comment faire hériter une interface ?
- Comment utiliser le mot-clé with ?
- Comment récupérer une date avec Dart ?
- Comment « caster » un type avec Dart ?
- Comment formater l'heure à partir d'une valeur décimale en Dart ?
- Comment concaténer une chaîne de caractères en Dart ?
- Comment créer une regex en Dart ?
- Comment déclarer une assertion ?
- Comment personnaliser le message d'erreur d'une assertion ?
- Peut-on propager une exception ?
- Comment créer une fonction anonyme ?
- Comment surcharger une méthode / fonction en Dart ?
- Comment déclarer une méthode / fonction avec des paramètres optionnels ?
- Comment utiliser le mot-clé rethrow ?
- Lorsque j'utilise innerHtml / appendHtml, mon css ne s'applique pas ! Pourquoi ?
- Comment utiliser NodeValidatorBuilder ?
- Comment alléger mes appels de méthodes ?
- Dart supporte-t-il les méthodes "inline" ?
- Quel est l'équivalent de htmlspecialchars de PHP en Dart ?
- Comment lire une chaîne caractère par caractère ?
- TypeScript, Dart; Lequel choisir ?
[Traduction de la FAQ officielle]
Oui et non. Nous pensons que JavaScript peut changer pour du génie logiciel plus productif, des éditeurs et environnements de développement plus intelligents et des applications Web aussi belles et agréables que les meilleures applications clientes peuvent l'être. D'autre part, nous ne pensons pas que tout doit changer, et pourquoi changer ce qui n'est pas cassé ?
Dart, comme JavaScript, est un langage à typage dynamique. Il ajoute des annotations de type optionnelles pour vous aider à intercepter les erreurs plus tôt. Il enlève quelques fonctionnalités de JavaScript, telles que les prototypes et l'objet global : ceci simplifie la machine virtuelle, permet une exécution plus rapide, et rend plus faciles la complétion et le refactoring du code. Dart ajoute quelques commodités. Pour n'en nommer que quelques-unes :
- opérateurs définis par l'utilisateur. Nous aimons le code léger et lisible qu’ils donnent pour notre interface DOM ;
- syntaxe simplifiée pour les fonctions anonymes. Vous les utilisez beaucoup dans la programmation Web, maintenant elles ont fière allure. Avec l'implémentation correcte de this et une portée lexicale complète au niveau du bloc, aucun piège.
Dart est plus qu'une nouvelle syntaxe, c'est un langage complet avec sa propre sémantique. Dart diffère de JavaScript de nombreuses façons, y compris :
- uniquement true est vrai ;
- pas de undefined, juste null ;
- pas de coercition automatique de type avec ==, +, et d'autres opérateurs.
Par rapport à JavaScript, Dart vise à être plus rapide, plus régulier, et plus évolutif pour les gros programmes.
[Traduction de la FAQ officielle]
Eh bien, Java est typé statiquement, et Dart est typé dynamiquement. Dart a des annotations de type statique optionnelles, là où en Java elles sont obligatoires. Pour nous, ce sont de grandes différences dans la nature des deux langages. Dart est un langage à accolades, et il partage quelques mots clés avec Java, tels que extends et final, alors nous voyons pourquoi les gens font la comparaison. Honnêtement, nous aimons avoir une syntaxe simple et familière qui est facile à apprendre, même si cela signifie que c'est moins excitant.
Quelques-uns des nombreux autres exemples qui montrent comment Dart diffère de Java :
- la machine virtuelle Java est une machine virtuelle sous forme de bytecode, nécessitant la compilation préalable du code source. La machine virtuelle Dart exécute le code source ;
- le langage Dart prend en charge les collections littérales d'une façon concise pour créer des listes et des map ;
- Java supporte les modificateurs d’accès public, protected, package protected et private. Dart en supporte public et library-private ;
- Dart est purement orienté objet. Java possède des objets et des types primitifs ;
- le langage Dart a des mixins, des types statiques optionnels, des paramètres nommés, et plus encore.
[Traduction de la FAQ officielle]
L'idée d'annotations de type optionnelles est similaire. Celles de Dart sont plus agréables syntaxiquement.
Comparer le code compilateur Closure suivant :
Code JavaScript : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | // code compilateur Closure /** * @param {String} name * @return {String} */ makeGreeting = function(name) { /** @type {String} */ var greeting = 'hello ' + name; return greeting; } |
Avec le code Dart suivant:
Code Dart : | Sélectionner tout |
1 2 3 4 5 6 | // code Dart String makeGreeting(String name) { String greeting = 'hello $name'; return greeting; } |
[Traduction de la FAQ officielle]
Dart et CoffeeScript sont inspirés par JavaScript, et les deux peuvent être retraduits en JavaScript. Ils font des choix différents, en particulier dans la saveur de leur syntaxe. Nous pensons qu'il est juste de dire que sémantiquement, Dart diffère plus de JavaScript que CoffeeScript ; cela peut entraîner une traduction ligne par ligne plus réduite, mais nous pensons que le code JavaScript généré par Dart peut avoir une taille et une vitesse excellentes.
Dart introduit de nouvelles sémantiques, tandis que CoffeeScript conserve la sémantique de JavaScript.
Si vous aimez CoffeeScript pour son ambiance plus structurée que le JavaScript pur, vous pourriez apprécier les annotations statiques de type optionnelles de Dart.
[Traduction de la FAQ officielle]
TypeScript et Dart ont des objectifs similaires : ils permettent de créer facilement des applications Web à grande échelle. Cependant, leurs approches sont assez différentes. TypeScript maintient une rétrocompatibilité avec JavaScript, tandis que Dart se détache délibérément de certaines parties de la syntaxe et la sémantique de JavaScript afin d'éradiquer des classes de bogues et améliorer les performances. Le Web a souffert trop longtemps de trop peu de choix, et nous pensons que les deux, Dart et TypeScript, pointent vers un avenir meilleur pour les développeurs Web. Vous pouvez lire une réponse plus complète sur notre blog.
[Traduction de la FAQ officielle]
Dart et Go sont tous les deux des langages initiés chez Google, mais ils sont indépendants et ont des objectifs différents. En conséquence, ils font des choix différents, et sont des langages de natures très différentes, même si nous essayons d'apprendre du travail des autres.
[Traduction de la FAQ officielle]
Les raisons sont diverses, et dépendent du langage dont il est question.
Pour les langages qui sont assez différents de JavaScript : il est important pour Dart de compiler vers du JavaScript efficace. Notre expérience en GWT nous montre que si le langage source est trop différent de JavaScript, un code complexe de sortie est nécessaire dans certains cas pour émuler le comportement du langage source. Cela peut entraîner des fluctuations de performance qui ne sont pas transparentes pour le programmeur.
Pour les langages moins courants : nous pensons que façonner Dart sur le modèle de ces derniers pourrait, dans l'ensemble, nuire à son adoption. Notre équipe inclut des adeptes de ces langages, et si nous pensons Dart capable d'englober les fonctionnalités intéressantes de nos langages préférés afin d'encourager une large adoption, nous serions tentés, mais nous pensons être suffisamment occupés à l'introduction d'un nouveau langage.
Pour les langages qui sont « plus dynamiques » que Dart : celui-ci troque délibérément cette modification arbitraire lors de l'exécution en échange de meilleurs outils et performances.
[Traduction de la FAQ officielle]
Nous avons conçu certaines belles fonctionnalités syntaxiques comme les arguments du constructeur précédés par this. et => pour les fonctions unilignes, mais nous sommes d'accord que Dart préfère la familiarité à la surexcitation.
[Traduction de la FAQ officielle]
En sa version initiale, Dart ne disposait de rien dans ce genre, mais les futures versions de Dart peuvent ajouter des fonctionnalités dynamiques de ce genre. Le jeu de fonctionnalités ne correspond pas exactement à votre question, mais nous espérons qu'il va servir les mêmes fins. Quand on verra ce qui sera ajouté, chacun pourra décider comment il classifie le langage.
Ce qui est important pour nous, c'est que tout ce que vous voulez faire avec un langage dynamique, vous pouvez également le faire avec Dart sans vous sentir à l'étroit. Vous devriez être en mesure de concevoir votre système sans l'ingérence des règles statiques, et de le modifier en temps réel pendant le développement et parfois au moment de l'exécution.
Par exemple, Dart n'est pas susceptible de supporter l'évaluation d'une chaîne de caractères en code dans le contexte actuel, mais il peut prendre en charge le chargement de ce code de manière dynamique dans un nouvel objet Isolate. Dart n'est pas susceptible de soutenir l'ajout de champs à une valeur, mais il peut (grâce à un système de miroir) supporter l'ajout des champs à une classe, et vous pouvez effectivement ajouter des méthodes utilisant noSuchMethod(). L'utilisation de ces fonctionnalités aura un coût en termes d'exécution ; il est important pour nous de minimiser ce coût pour les programmes qui ne les utilisent pas.
[Traduction de la FAQ officielle]
Le support pour la réflexion est fourni par l'API miroirs.
[Traduction de la FAQ officielle]
Le langage est maintenant à la version 1.0, mais nous nous attendons à une évolution future de la norme. Elle pourrait être en mesure d'inclure votre fonctionnalité, même si elle ne peut pas tout inclure. Certaines fonctionnalités ne correspondent pas à la nature de base du langage, et certaines ne s’intègrent pas bien. La simplicité est le cadeau le plus important que nous puissions faire aux futurs développeurs.
Veuillez regarder la liste des questions Dart pour voir si une demande similaire ne s'y trouve pas déjà, sinon ajoutez-en une nouvelle. Faites une argumentation solide pour votre demande. Un exemple de code avec et sans votre fonctionnalité constitue une bonne preuve ; une quantité appréciable de code qui démontre la nécessité est une meilleure preuve.
Veuillez ne pas être étonné si les concepteurs de Dart disent « non » par défaut, surtout pour l'instant. Il est beaucoup plus pénible d'enlever une fonctionnalité du langage que de l'ajouter, alors Dart est susceptible d'ajouter d'abord les fonctionnalités les plus évidentes et de revenir sur les autres plus tard. Et il y a tout simplement plus de fonctionnalités possibles dans le monde qui peuvent être ajoutées à un seul langage sans en faire du hachis. Mais nous sommes très reconnaissants pour les suggestions et les contributions. Nous espérons que vous verrez notre reconnaissance à travers les choix de conception soignée et une communication équitable à ce sujet.
Dart dispose d'un module (dart:js) qui permet d'émuler certaines ressources propres au JavaScript, à défaut de ne pas posséder d'une réelle alternative.
Pour émuler une ou plusieurs fonctions, voici comment vous pouvez procéder :
Code dart : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 | import 'dart:html'; import 'dart:js'; void main() { Element elem = querySelector('#area'); JsObject selection = context.callMethod('getSelection', []); elem.onMouseUp.listen( (event) => print(selection.callMethod('toString', [])) ); } |
Dans cet exemple, le contenu de la sélection sera affiché uniquement lorsque l'utilisateur aura relâché le clic de sa souris. Mais vous pouvez bien évidemment modifier l'événement écouté.
Dart dispose d'un module qui réunit toutes les collections. Elles se trouvent donc dans le module dart:collection.
La manière la plus simple pour créer une map est la suivante :
Code dart : | Sélectionner tout |
1 2 3 4 5 6 7 8 | void main() { var myMap = { "username":"Phaeris"; } } |
En faisant appel à la fonction print(myMap.runtimeType);, vous remarquerez que les maps par défaut sont des LinkedHashMap, vous n'avez donc pas besoin de préciser la classe si vous comptiez utiliser ce genre de collections.
Pour préciser le type d'entrée, il vous suffit de faire ceci :
Code dart : | Sélectionner tout |
1 2 3 4 5 6 7 8 | void main() { var myMap = <String, String> { "username":"Phaeris"; } } |
La gestion des exceptions avec Dart
Tout comme Java, C++, Ruby ou bien d'autres, Dart dispose d'un système de gestion des erreurs très précis.
Attention tout de même, Dart n'affiche pas automatiquement l'intégralité de la pile lorsque vous essayez de renvoyer le résultat de l'erreur sur la sortie standard, nous allons donc voir comment faire.
Pour lancer une erreur, il va falloir utiliser le mot-clé throw comme ceci :
Code dart : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | void displayUnsignedInteger(int i) { if(i >= 0) { print(i); } else throw "i's value is negative."; } |
Lorsque vous passerez un entier négatif, le message d'erreur se lèvera. Seulement, vous ne disposerez d'aucune indication quant à l'endroit où se trouve ce fameux message, et donc l'erreur. Voici comment procéder :
Code dart : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | void displayUnsignedInteger(int i) { if(i >= 0) { print(i); } else throw "i's value is negative."; } try { displayUnsignedInteger(-1); }catch(e, stacktrace) { print(stacktrace); } |
Vous obtiendrez alors un message de la sorte :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | i's value is negative. at dart.wrapException (<anonymous>:590:17) at dart.throwExpression (<anonymous>:603:15) at dart.main (<anonymous>:1422:11) at <anonymous>:1716:9 at init.currentScript (<anonymous>:1700:7) at <anonymous>:1711:5 at <anonymous>:1719:3 at replaceJavaScript |
Code dart : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | void displayUnsignedInteger(int i) { if(i >= 0) { print(i); } else throw new Exception("i's value is negative."); } |
Pour effectuer des tâches asynchrones avec Dart, c'est relativement simple. Il suffit d'importer le module suivant :
Code Dart : | Sélectionner tout |
import 'dart:async';
Il vous permettra d'avoir accès à la classe Future et au mot-clé async (ce dernier permettant donc d'attacher une fonction de callback sur votre méthode / fonction).
Voici comment procéder :
Code Dart : | Sélectionner tout |
1 2 3 4 | myFunction().then((_){ /* Votre code */ }); |
Bien évidemment, myFunction() doit être déclarée de la façon suivante pour que ça fonctionne :
Code Dart : | Sélectionner tout |
1 2 3 4 5 6 | Future myFunction() async { /* Votre code */ /* La fonction doit forcément renvoyer un objet Future pour que la fonction puisse posséder une fonction de callback ! */ } |
Gestion des exceptions
Pour catcher les éventuelles erreurs, il vous faudra bien évidemment les déclarer dans le corps de votre fonction, puis :
Code Dart : | Sélectionner tout |
1 2 3 4 5 6 | myFunction().then((_){ /* Votre code */ }, onError: (e){ print(e); }); |
Vous pouvez également obtenir la trace de la pile en ajoutant un paramètre à la closure :
Code Dart : | Sélectionner tout |
1 2 3 4 5 6 7 | myFunction().then((_){ /* Votre code */ }, onError: (e, stack){ print(e); print(stack); }); |
Rattrapant alors les erreurs déclarées.
Comment utiliser le « local storage » avec Dart ?
L'utilisation du local storage avec Dart est très similaire à celle du JavaScript, voici un exemple :
Code dart : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | import 'dart:html'; void main() { Storage localStorage = window.localStorage; localStorage['username'] = "John"; localStorage['matricule'] = "117"; } |
Le navigateur de l'utilisateur dispose désormais des deux clés « username » et « matricule ».
Pour lire ces données à la prochaine visite de l'utilisateur, voici la marche à suivre :
Code dart : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 | import 'dart:html'; void main() { Storage localStorage = window.localStorage; String username = localStorage['username']; String matricule = localStorage['matricule']; if(username != null && matricule != null) { print("Welcome home, $username $matricule"); } } |
Conclusion
En plus d'assurer la persistance des données, le local storage rend les opérations sur les données utilisateurs moins fastidieuses (comme la recherche de la valeur désirée, par exemple).
Oui, mais elles ne possèdent pas la même syntaxe.
Dart ne fait pas la différence entre une classe abstraite possédant le mot-clé abstract et une classe abstraite possédant le mot-clé interface comme on peut le voir en Java.
Pour déclarer une interface, il suffit d'écrire ceci :
Code dart : | Sélectionner tout |
1 2 3 4 5 | abstract class ClassName { doSomething(); } |
Dart a hérité du mot-clé implements que l'on retrouve en Java pour faire hériter les propriétés d'une interface à une autre classe, il suffit donc d'écrire ceci :
Code dart : | Sélectionner tout |
1 2 3 4 | class YourClass implements YourInterface { } |
Le mot-clé with permet la création d'une nouvelle classe héritant elle-même de deux autres classes non abstraites.
Vous pouvez donc procéder de deux manières :
- fusionner deux classes pour obtenir le meilleur de chacune d'entre elles. Il vous suffit de créer une nouvelle classe de manière concise :
Code dart : Sélectionner tout 1
2
3
4
5
6
7
8
9
10class A{ String name = "John"; } class B { String matricule = "117"; } class C = A with B;
- vous souhaitez toujours fusionner vos classes, mais vous aimeriez pouvoir ajouter de nouvelles fonctionnalités à la nouvelle classe. Déclarez-la comme ceci :
Code dart : Sélectionner tout 1
2
3
4
5
6
7
8
9
10
11
12
13class A{ String name = "John"; } class B { String matricule = "117"; } class C extends A with B { }
C'est simple, il suffit d'utiliser la classe DateTime.
Pour récupérer la date d'aujourd'hui, par exemple, il faut écrire l'instruction suivante :
Code dart : | Sélectionner tout |
DateTime today = new DateTime.now();
Résultat :
Vous pouvez obtenir une valeur en particulier (par exemple le mois, le jour, etc.) en écrivant ceci :
Code dart : | Sélectionner tout |
1 2 3 4 5 6 7 | var date = new DateTime.now(); date.month; // Le mois date.day; // Le jour date.second; // Les secondes date.minute; // Les minutes date.hour; // Etc. |
Si sa syntaxe hérite principalement de celle de Java, il y a cependant quelques subtilités, tout comme le casting.
Pour convertir un type de données, il faut utiliser le mot-clé as :
Code dart : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class Mere { void sayHello() { print("Hello"); } } class Fille extends Mere{} void main() { var fille = new Fille(); var mere = fille as Mere; print(mere); mere.sayHello(); } |
Résultat :
Hello
Le SDK ne dispose pas encore d'outils officiels pour formater l'heure de cette manière, mais vous pouvez utiliser cette fonction :
Code dart : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | /** * Example:<br> * <code> * formatMe(2.5); // => 2:30:0 (2 hours:30 minutes:0 seconds) * </code> * @param hour Can be a Double|Integer object * @return formatted hour */ String formatMe(hour) { if(hour is num) { if(hour > 0.0) { double base = hour * 3600; int base_minute = (base~/60); int seconds = (base%60).round(); int hours = (base_minute~/60); int minutes = base_minute%60; return "${hours.toString()}:${minutes.toString()}:${seconds.toString()}"; } throw new Exception("hour =< 0"); } throw new Exception("hour is ${hour.runtimeType} and should be num instance."); } void main() { print(formatMe(1.1111111111111111111)); } |
Vous pouvez exécuter l'exemple de la fonction main().
Résultat :
Pour concaténer une chaîne, vous avez trois possibilités :
- avec l'opérateur + :
Code dart : Sélectionner tout String name = "my" + "name" + "is" + "Songbird";
- en utilisant des white space :
Code dart : Sélectionner tout String name = "my" "name" "is" "Songbird";
- en utilisant le jeu d'opérateurs ${} :
Code dart : Sélectionner tout 1
2
3String name = "Songbird"; print("My name's ${name}");
La création des expressions rationnelles peut être, de prime abord, moins intuitive qu'en JavaScript.
Pour créer une regex en Dart, il faut créer un objet RegexExp :
Code dart : | Sélectionner tout |
1 2 3 4 5 | void main() { final RegExp regex = new RegExp("^M"); } |
Notre regex « matchera » si la ligne commence par un M majuscule.
Voici un exemple d'utilisation :
Code dart : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | void main() { final RegExp regex = new RegExp("^M", caseSensitive: false); final String string = "My awesome regex !"; if(string.contains(regex)) { print("It works !"); } try { var words = regex.allMatches(string); // Renvoie une instance de la classe Iterable<Match> contenant tous les éléments respectant les critères de la regex if(words.isNotEmpty) { for(var word in words) { print("word=${word.group(0)}"); // On récupère la première entrée (et la seule pour cet exemple) } } else throw new Exception("words list is empty."); }catch(e, stack) { print(stack); } // On protège l'opération avec un try / catch } |
Tout comme nous pourrions le faire en Java, il faut utiliser le mot-clé assert comme ceci :
Code dart : | Sélectionner tout |
assert(votre_condition);
Attention toutefois, les parenthèses ne sont pas optionnelles !
Exemples :
Code dart : | Sélectionner tout |
1 2 | assert 2 > 1; // Erreur assert(2>1); // Renvoie true |
Malheureusement, Dart ne dispose pas de messages personnalisés pour les assertions comme nous pourrions le voir en Java :
Code Java : | Sélectionner tout |
assert votre_expression : "votre_message";
Nous devrons pour le moment nous contenter de la stacktrace.
En Java, grâce au mot-clé throws, il est possible de propager l'exception à l'extérieur d'une méthode et / ou d'un constructeur pour laisser l'utilisateur gérer les erreurs à sa guise.
En revanche, Dart ne supporte pas cette fonctionnalité.
Le langage part du principe que si vous créez une ressource destinée à être utilisée par quelqu'un d'autre, c'est à vous de gérer l'erreur. Facilitant alors le débogage pour les débutants qui ont tendance à faire ceci :
Code Java : | Sélectionner tout |
1 2 3 4 5 | try { java.io.BufferedReader buffer = new BufferedReader(new java.io.FileReader(new java.io.File("yourFile"))); }catch(IOException ioe){} // A ne jamais faire ! |
L'exemple est en Java, mais ça aurait pu être le cas en Dart s'il supportait ce genre de fonctionnalités.
Lorsque vous avez besoin de lancer une exception, vous serez obligé de la catcher directement comme ceci :
Code dart : | Sélectionner tout |
1 2 3 4 5 6 7 8 | try { if(1 > 2){ throw new Exception("An error was occurred");} }catch(e, s) { print(s); } |
Vous pouvez d'ailleurs essayer par vous-même d'adopter cette syntaxe :
Code dart : | Sélectionner tout |
1 2 | void my_function() throws Exception{} |
ça ne fonctionnera pas.
En Dart, vous êtes dispensé d'utiliser le mot-clé function.
Vous pouvez procéder comme ceci :
Code dart : | Sélectionner tout |
1 2 | var my_closure = () => print("Hello world !"); // Si votre fonction est inline, vous pouvez adopter cette syntaxe |
Ou alors :
Code dart : | Sélectionner tout |
1 2 3 4 5 | var my_closure = () { print("Hi, there."); }; |
Attention à toujours conserver les deux points-virgules pour terminer la déclaration de la fonction.
Ce n'est pas possible.
Les méthodes / fonctions en Dart disposent en revanche de paramètres optionnels.
Pour déclarer des paramètres optionnels, vous devez respecter cette syntaxe :
Code dart : | Sélectionner tout |
1 2 | void my_function(final String hello, [final String world]){} |
Vous pouvez également affecter une valeur par défaut aux paramètres optionnels :
Code dart : | Sélectionner tout |
void my_function(final String hello, [final String world = "Hello world"]){}
Le mot-clé rethrow pourrait être comparé au mot-clé throws en Java, mais il n'est pas positionné de la même manière.
Il permet de propager une erreur jusqu'au try / catch suivant, qui, lui, sera chargé de la traiter une bonne fois pour toutes (ou de la propager, si besoin, évidemment).
Le mot-clé doit se trouver dans le catch pour fonctionner correctement, comme ceci :
Code dart : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | void main() { try { test(); }catch(e, s) { print("$s"); } } void test() { try { throw 1; }catch(e, s) { rethrow; } } |
Par défaut, Dart nettoie les injections HTML avant de les ajouter au document. Seulement, lorsqu'il effectue le nettoyage, il supprime également tous les attributs de l'élément, y compris l'attribut style, affichant alors simplement votre texte.
Pour remédier au problème, il faut alors implémenter la classe abstraite NodeValidator dans une classe que vous aurez préalablement déclarée.
L'interface NodeValidator se charge de retenir les règles à faire respecter aux prochains morceaux de code HTML.
Voici un exemple d'utilisation :
Code dart : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import 'dart:html'; void main() { var body = querySelector("body"); body.setInnerHtml('<span style="color: red;">Hello, friend.</span>', validator: new TrustedNodeValidator()); /** On utilise la méthode setInnerHtml pour injecter et respecter les règles personnalisées */ } /** Déclaration et implémentation de l'interface NodeValidator */ class TrustedNodeValidator implements NodeValidator { bool allowsElement(Element element) => true; /** On autorise les éléments HTML */ bool allowsAttribute(element, attributeName, value) => true; /** On leur permet de posséder des attributs */ } |
Premièrement, la classe NodeValidatorBuilder n'est pas un passage obligatoire pour créer des filtres personnalisés régissant les éléments susceptibles d'être injectés dynamiquement dans votre page, mais elle contribue à une verbosité moins importante et à économiser une classe (qui serait) uniquement dédiée à l'implémentation de la classe NodeValidator. (Nous n'aborderons pas cette méthode ici)
La classe NodeValidatorBuilder dispose donc de *deux* constructeurs:
- NodeValidatorBuilder() (constructeur par défaut (n'autorise aucun élément ni attribut, n'en ressort que du texte))
- NodeValidatorBuilder.common() (autorise l'html5 ainsi que l'élément <template>)
Voici un exemple d'utilisation pour les deux constructeurs:
Code dart : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 | import 'dart:html'; /*On importe le module/bibliothèque dart:html*/ void main() { var default_sanitizer = new NodeValidatorBuilder() ..allowHtml5() ..allowInlineStyles(); /* Ou: */ var sanitizer = new NodeValidatorBuilder.common()..allowInlineStyles(); var element = document.body; element.appendHtml('<p style="color: purple">Hi, friend !</p>', validator: sanitizer); } |
Vous pouvez bien entendu retrouver (et tester) cet exemple ici.
Il arrive très souvent d'appeler de nombreuses méthodes sur une seule instance, ce qui peut parfois rendre très verbeux ces appels.
Dart propose une alternative à cette écriture quelque peu répétitive en permettant au développeur d'écrire uniquement les identifiants des méthodes précédées de deux points ("..") comme ceci:
Code dart : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class Foo { Foo(); int bar() => 0; bool thecakeisalie() => true; /*huge method id*/ } void main() { var foo = new Foo() ..bar() ..thecakeisalie(); } |
Attention:
Le point virgule ( ; ) doit obligatoirement suivre la dernière méthode appelée, sinon l’instruction ne veut plus rien dire aux yeux du compilateur. (ou de la VM)
Oui.
Une méthode inline en Dart se déclare comme ceci:
Code dart : | Sélectionner tout |
1 2 3 4 5 6 7 | int foo() => 0; /* inline method */ void main() { /* multiline method */ } |
Tous les outils chargés de la sécurité contre les injections de code non désirées se trouvent dans le package dart:convert.
Vous aurez généralement besoin d'utiliser les deux classes suivantes :
L'une étant, en quelque sorte, l'amorce de l'autre, vous devrez les utiliser de cette manière :
Code dart : | Sélectionner tout |
1 2 3 4 5 6 7 | var sanitizer = const HtmlEscape(HtmlEscapeMode.UNKNOWN); /** Le constructeur de la classe HtmlEscape doit être obligatoirement statique. Le mode par défaut est UNKNOWN, mais vous pouvez bien entendu découvrir les autres modes dans les liens dans la liste ci-dessus. Il est bien sûr inutile de préciser la propriété UNKNOWN si vous souhaitez ne rien changer, ce n'était qu'à titre d'exemple. */ |
Puis vous pouvez désormais préparer votre code html malicieux :
Code : | Sélectionner tout |
var html = "<span name='test'>Hello!<!--</span>";
Voici un exemple :
Code dart : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | import 'dart:convert'; /** Ne pas oublier l'import ! */ void main() { var sanitizer = const HtmlEscape(HtmlEscapeMode.UNKNOWN); var html = "<span name='test'>Hello!<!--</span>"; print(sanitizer.convert(html)); } |
Dart ne supporte pas le type primitif char dans ses types préfaits, il n'existe donc pas non plus de solution prête à l'emploi pour décortiquer une chaîne dans la classe String.
Voici une solution :
Code dart : | Sélectionner tout |
1 2 3 4 5 6 7 | void main() { String my_awesome_string = "Hi, dude !"; var tmp = my_awesome_string.split(new RegExp("(?=[a-z])", caseSensitive:false)); for(String letter in tmp) print(letter); } |
Permettant ainsi d'opérer sur les caractères de votre choix.
Dart et TypeScript, bien qu'étant de prime abord de simples surcouches JS, sont deux outils bien différents.
L'un privilégie la performance du programme écrit tout en s'éloignant drastiquement de la syntaxe de Javascript, en plus de proposer une API différente. (qui était tout d'abord dédiée à la machine virtuelle)
L'autre se rapproche plus d'une surcouche composée "principalement" de sucres syntaxiques, tout en conservant un code lisible et permettant à des développeurs JavaScript de bénéficier d'un support plus conséquent en terme de débogage grâce au compilateur de TypeScript et du typage statique optionnel.
En somme, tout dépend de votre besoin.
TypeScript permet d'être compris par un développeur JavaScript sans problème, Dart non.
En revanche dart2js sera plus rigoureux en terme d'optimisation et de propreté du code. (élimination du code mort)
Proposer une nouvelle réponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour çaLes sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.