Dart cheat sheet
Introduction Rapide à Dart
Dart est un langage de programmation optimisé pour le développement d’applications multiplateformes, notamment pour les interfaces utilisateur mobiles et web. Conçu par Google, il se distingue par sa facilité d’apprentissage, sa syntaxe claire et sa capacité à compiler en code natif ou JavaScript. Dart est la pierre angulaire de Flutter, le kit de développement logiciel (SDK) de Google pour la création d’interfaces utilisateur attrayantes et performantes sur mobile, web et desktop.
Caractéristiques Principales
- Fortement Typé: Dart encourage l’utilisation de types explicites mais n’en fait pas une obligation grâce à l’inférence de type.
- Compilation Juste-à-Temps (JIT) et Avant-Exécution (AOT): JIT pour un cycle de développement rapide (avec rechargement à chaud) et AOT pour des performances optimisées en production.
- Concurrentiel: Supporte la programmation asynchrone grâce aux Futures et Streams.
- Orienté Objet: Tout est un objet dans Dart, y compris les nombres, les fonctions et les nulls.
Hello World en Dart
void main() {
print('Hello, World!');
}
Ce programme affiche le classique “Hello, World!” sur la console. Le point d’entrée d’une application Dart est la fonction main()
.
Syntaxe de Base de Dart
Commentaires
- Ligne:
// Mon commentaire
- Bloc:
/* Mon commentaire */
Variables
var nom = 'Dart';
// Inférence de typeString message = 'Hello';
// Typé explicitement
Types
- Entiers:
int age = 30;
- Flottants:
double prix = 10.99;
- Chaînes:
String nom = 'Dart';
- Booléens:
bool estVrai = true;
- Listes:
List<int> numeros = [1, 2, 3];
- Maps:
Map<String, String> dictionnaire = {'cle': 'valeur'};
- Sets:
Set<String> noms = {'Dart', 'Flutter'};
Opérateurs
- Arithmétiques:
+
,-
,*
,/
- Comparaison:
==
,!=
,>
,<
- Logiques:
&&
,||
,!
Suctures de Contrôle dans Dart
Conditions
if
:if (condition) { // code si vrai }
else if
etelse
:if (condition) { // code si vrai } else if (autreCondition) { // code si autreCondition est vrai } else { // code si faux }
switch
:switch (variable) { case valeur1: // code si variable == valeur1 break; case valeur2: // code si variable == valeur2 break; default: // code si aucune correspondance }
Boucles
for
:for (int i = 0; i < 10; i++) { // code exécuté 10 fois }
forEach
(sur les collections):var liste = [1, 2, 3]; liste.forEach((item) { // code pour chaque élément });
while
:while (condition) { // code tant que condition est vrai }
do-while
:do { // code exécuté au moins une fois } while (condition);
Fonctions et Méthodes dans Dart
Déclaration de Fonctions
- Syntaxe de base:
returnType functionName(parameters) { // Corps de la fonction }
- Exemple:
void direBonjour() { print('Bonjour'); }
Paramètres et Retour
- Avec paramètres:
void saluer(String nom) { print('Bonjour, $nom'); }
- Avec valeur de retour:
String creerSalutation(String no return 'Bonjour, $nom'; }
Paramètres Optionnels
- Nominaux
{}
:void configurer({String couleur = 'blanc', bool actif = false}) { // Configuration }
- Positionnels
[]
:void direQuelqueChose(String message, [String ton = 'normal']) { // Message avec ton }
Fonctions Fléchées
- Syntaxe concise pour les fonctions retournant une expression:
void main() => print('Bonjour Dart');
Fonctions Anonymes
- Sans nom, utiles comme arguments:
var list = ['pommes', 'bananes']; list.forEach((item) { print(item); });
Méthodes
- Fonctions définies à l’intérieur d’une classe:
class Voiture { void klaxonner() { print('Tut tut!'); } }
Portée et Fermetures
- Les variables définies dans une fonction sont locales à celle-ci.
- Les fonctions peuvent capturer et manipuler des variables de portée supérieure.
Collections dans Dart
Listes
- Déclaration:
List<Type> nom = [valeur1, valeur2];
List<String> fruits = ['pomme', 'banane'];
- Accès:
nom[index];
print(fruits[0]); // 'pomme'
- Modification:
nom[index] = nouvelleValeur;
fruits[0] = 'fraise';
Maps
- Déclaration:
Map<KeyType, ValueType> nom = {'cle1': valeur1, 'cle2': valeur2};
Map<String, int> codesPostaux = {'Paris': 75000, 'Lyon': 69000};
- Accès:
nom[cle];
print(codesPostaux['Paris']); // 75000
- Modification:
nom[cle] = nouvelleValeur;
codesPostaux['Lyon'] = 69001;
Sets
- Déclaration:
Set<Type> nom = {valeur1, valeur2};
Set<String> nomsUniques = {'Alice', 'Bob'};
- Ajout:
nom.add(valeur);
nomsUniques.add('Charlie');
- Vérification:
nom.contains(valeur);
print(nomsUniques.contains('Alice')); // true
Opérations Courantes
- Longueur:
nom.length;
- Ajout/Suppression:
nom.add(valeur);
/nom.remove(valeur);
- Itération:
nom.forEach((valeur) => action);
- Filtrage:
nom.where((valeur) => condition);
- Transformation:
nom.map((valeur) => nouvelleValeur);
- Trie :
numbers.sort((a, b) => a.length.compareTo(b.length));
Collections Immutables
- Pour créer une liste, un set ou une map immuable, utilisez
const
:final List<String> villes = const ['Paris', 'Lyon']; final Set<String> couleurs = const {'rouge', 'vert'}; final Map<String, String> dictionnaire = const {'oui': 'yes', 'non': 'no'};
Les collections sont des structures de données fondamentales dans Dart, permettant de stocker et de manipuler des ensembles de données de manière efficace et intuitive.
Programmation Asynchrone dans Dart
Futures
- Un
Future
représente une valeur potentielle, ou une erreur, qui sera disponible à un moment donné dans le futur.Future<String> chargerDonnees() async { return 'Données chargées'; }
Async et Await
async
est utilisé pour déclarer une fonction asynchrone.await
est utilisé pour attendre qu’unFuture
se complète.void afficherDonnees() async { var donnees = await chargerDonnees(); print(donnees); }
Gestion des Erreurs
- Utilisez
try
,catch
, etfinally
pour gérer les erreurs dans des opérations asynchrones.Future<void> traiterDonnees() async { try { var donnees = await chargerDonnees(); print(donnees); } catch (e) { print('Erreur: $e'); } finally { print('Nettoyage'); } }
Streams
- Un
Stream
fournit une séquence de données asynchrones.Stream<int> compter() async* { for (int i = 1; i <= 3; i++) { await Future.delayed(Duration(seconds: 1)); yield i; // Envoie les données dans le stream } }
- Consommation d’un
Stream
:void ecouterComptage() async { await for (int compteur in compter()) { print(compteur); } }
Utilisation de Futures et Streams
- Les
Future
etStream
sont essentiels pour les opérations I/O, comme les requêtes réseau ou les lectures/écritures de fichiers, permettant à votre application de rester réactive.
La programmation asynchrone dans Dart est un concept clé pour le développement d’applications réactives, particulièrement dans le contexte de Flutter pour le développement d’applications mobiles.
Tests dans Dart
Introduction aux Tests
- Les tests sont essentiels pour assurer la qualité et la fiabilité du code.
- Dart utilise le package
test
pour écrire et exécuter des tests unitaires et des tests d’intégration.
Installation du Package de Test
- Ajoutez
test
comme une dépendance de développement danspubspec.yaml
:dev_dependencies: test: ^1.16.0
Écrire un Test Unitaire
- Créez un fichier dans le dossier
test/
de votre projet. - Utilisez
test()
pour définir un test:import 'package:test/test.dart'; void main() { test('my first unit test', () { var answer = 42; expect(answer, 42); }); }
Assertions
expect(actual, matcher)
est utilisé pour vérifier que la valeur réelle correspond à ce qui est attendu.- Dart fournit un ensemble riche de
matchers
pour différents types de vérifications.
Exécuter les Tests
- Dans le terminal, naviguez vers le répertoire de votre projet et exécutez
dart test
Tests d’Intégration
- Les tests d’intégration vérifient que différentes parties de votre application fonctionnent ensemble comme prévu.
- Ils peuvent nécessiter un environnement spécifique, comme une base de données ou un serveur web.
Mocking
- Le
mocking
est une technique utilisée pour simuler le comportement des dépendances réelles dans les tests. - Utilisez le package
mockito
pour créer des objets factices et définir leurs comportements.
Exemple de Mocking
- Ajoutez
mockito
à vosdev_dependencies
. - Créez des mocks pour tester le comportement en interaction avec des API externes ou des bases de données.
Organisation des Tests
- Regroupez des tests similaires en utilisant
group()
. - Utilisez des noms descriptifs pour vos tests et groupes pour faciliter la compréhension et le débogage.
La mise en place d’une suite de tests robuste est une étape cruciale dans le développement de logiciels, permettant de détecter et corriger les erreurs rapidement, ainsi que de s’assurer que les nouvelles fonctionnalités ne cassent pas le comportement existant de l’application.