En Dart, les fonctions sont aussi des objets, ce qui diffère légèrement des autres langages de programmation.
Les fonctions sont des objets de première classe
Dart est un langage entièrement orienté objet : les fonctions elles-mêmes sont des objets, de type Function.
Elles peuvent être affectées à des variables et transmises en paramètres à d’autres fonctions ;
Les instances de classe peuvent être appelées directement comme des fonctions
1 Définition standard d’une fonction
// Déclaration complète avec annotation du type de retour et des paramètres
bool isNoble(int atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
Langage du code : Dart (dart)
Exemple complet
// Tableau de correspondance des numéros atomiques des gaz nobles
final Map<int, String> _nobleGases = {
2: 'He',
10: 'Ne',
18: 'Ar',
36: 'Kr',
54: 'Xe',
86: 'Rn',
};
// Déclaration complète avec type de retour et types de paramètres
// Le type int n’accepte pas null ; utilisez int? pour autoriser des paramètres nullables
bool isNoble(int? atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
void main() {
print(isNoble(null)); // null n’est pas une clé de la carte → false
print(isNoble(2)); // Correspond à un gaz noble → true
print(isNoble(9)); // Aucune correspondance → false
print(isNoble(86)); // Correspond à un gaz noble → true
}
Langage du code : Dart (dart)
false
true
false
trueLangage du code : JavaScript (javascript)
2 Omettre les annotations de type
Le guide de style Effective Dart recommande d’indiquer explicitement tous les types pour les API publiques exposées à l’extérieur.
Vous pouvez omettre les annotations de type pour les fonctions internes privées
Exemple
final Map<int, String> _nobleGases = {
2: 'He',
10: 'Ne',
18: 'Ar',
36: 'Kr',
54: 'Xe',
86: 'Rn',
};
isNoble(atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
void main() {
print(isNoble(null)); // null n’est pas une clé de la carte → false
print(isNoble(2)); // Correspond à un gaz noble → true
print(isNoble(9)); // Aucune correspondance → false
print(isNoble(86)); // Correspond à un gaz noble → true
}
Langage du code : Dart (dart)
Dans l’exemple ci-dessus, la fonction isNoble n’indique pas le type de retour bool ni le type de paramètre int?, mais elle fonctionne normalement.
Lorsque vous ne spécifiez pas de type, Dart réalise une inférence de type automatique :
- Paramètre
atomicNumber: sans type explicite → inféré commedynamic(type dynamique, accepte n’importe quelle valeur : nombres, chaînes, null) - Valeur de retour : sans annotation de type en tête → Dart déduit que le type de retour est
boolà partir de l’expression aprèsreturn, sans l’écrire dans le code
Pourquoi les API publiques doivent absolument avoir des types explicités ?
Lisibilité : les développeurs qui appellent votre fonction voient immédiatement les types des entrées et de la sortie, sans avoir à lire le code interne pour deviner ;
Sécurité de type : le type dynamic désactive la vérification statique ; transmettre un mauvais type ne provoque pas d’erreur à la compilation et peut entraîner des crashs en production ;
Assistants IDE : les annotations de type activent l’autocomplétion et les infos de paramètres dans l’éditeur ; sans types, l’IDE ne peut pas afficher des suggestions précises.
Quand peut-on omettre les annotations de type ?
Uniquement recommandé pour le code privé local : fonctions utilisées exclusivement dans le fichier courant et jamais appelées de l’extérieur.
Syntaxe fléchée abrégée (=>)
Lorsque le corps de la fonction (le code entre {}) ne contient qu’une seule expression de retour, vous pouvez utiliser la syntaxe fléchée.
Exemple
bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
Langage du code : Dart (dart)
=> expréquivaut à{ return expr; };- Seules des expressions peuvent être écrites entre la flèche et le point-virgule ; les instructions comme
ifsont interdites (utilisez un opérateur ternaire à la place).
// Tableau de correspondance des numéros atomiques des gaz nobles
final Map<int, String> _nobleGases = {
2: 'Hélium',
10: 'Néon',
18: 'Argon',
36: 'Krypton',
54: 'Xénon',
86: 'Radon',
};
// Fonction fléchée abrégée : retour direct d’une expression sur une ligne, équivalent à une fonction bloc avec return
bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
void main() {
// Test des gaz nobles existants
print(isNoble(2)); // true
print(isNoble(18)); // true
// Test des éléments courants
print(isNoble(6)); // false (Carbone)
print(isNoble(99)); // false (aucun élément correspondant)
}
Langage du code : Dart (dart)

Parameters Paramètres
Les fonctions acceptent les paramètres positionnels obligatoires, suivis d’un seul choix possible : paramètres nommés ou paramètres positionnels optionnels ; ils ne peuvent pas être mélangés.
La virgule finale , est autorisée lors de la définition ou de l’appel des paramètres pour améliorer la lisibilité du code.
1. Paramètres nommés Named parameters
Encadrés par {}, ils sont optionnels par défaut ; ajoutez required pour imposer leur transmission.
1) Paramètres nommés nullables basiques (pas de valeur par défaut, valent null par défaut, le type doit être nullable avec ?)
void enableFlags({bool? bold, bool? hidden}) {}
// Spécifiez explicitement les noms des paramètres lors de l’appel
enableFlags(bold: true, hidden: false);
Langage du code : Dart (dart)
Exemple complet
/// Activer les drapeaux de style texte : gras, masqué
void enableFlags({bool? bold, bool? hidden}) {
print('Gras : $bold, Masqué : $hidden');
}
void main() {
// Transmettre tous les paramètres nommés
enableFlags(bold: true, hidden: false);
// Ne transmettre qu’un seul paramètre nommé, l’autre vaut null
enableFlags(bold: true);
// Ne transmettre que hidden
enableFlags(hidden: true);
// Ne transmettre aucun paramètre, les deux valent null
enableFlags();
}
Langage du code : Dart (dart)
Résultat d’exécution
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Gras : true, Masqué : false
Gras : true, Masqué : null
Gras : null, Masqué : true
Gras : null, Masqué : nullLangage du code : JavaScript (javascript)
2) Définir des valeurs par défaut constantes au moment de la compilation (pas besoin de type nullable car une valeur par défaut existe)
void enableFlags({bool bold = false, bool hidden = false}) {}
enableFlags(bold: true); // hidden utilise automatiquement false
Langage du code : Dart (dart)
Exemple
/// Activer les drapeaux de style texte : gras, masqué
void enableFlags({bool bold = false, bool hidden = false}) {
print('Gras : $bold, Masqué : $hidden');
}
void main() {
enableFlags();//Aucun paramètre transmis, les deux prennent la valeur par défaut false → Gras : false, Masqué : false
}
Langage du code : Dart (dart)
3) Paramètres nommés obligatoires avec required (Note : très utilisé dans les constructeurs de composants Flutter). L’exemple ci-dessous est du code Flutter, vous pourrez en apprendre davantage dans les cours Flutter.
const Scrollbar({super.key, required Widget child});
// Les paramètres required acceptent aussi les types nullables
const Scrollbar({super.key, required Widget? child});
Langage du code : Dart (dart)
Dart n’impose pas de placer les paramètres nommés à la fin de la liste ; ils peuvent être insérés n’importe où dans la liste des paramètres
repeat(times: 2, () {})Langage du code : CSS (css)
2. Paramètres positionnels optionnels Optional positional parameters
Encadrés par [], ils valent null si omis ; vous pouvez définir une valeur par défaut constante.
// Sans valeur par défaut, type marqué d’un ?
String say(String from, String msg, [String? device]) {
var result = '$from says $msg';
if (device != null) result = '$result with a $device';
return result;
}
assert(say('Bob', 'Howdy') == 'Bob says Howdy');
assert(say('Bob', 'Howdy', 'smoke signal') == 'Bob says Howdy with a smoke signal');
Langage du code : Dart (dart)
Exemple complet
// [String? device] paramètre positionnel optionnel sans valeur par défaut, vaut null si omis
String say(String from, String msg, [String? device]) {
var result = '$from says $msg';
if (device != null) {
result = '$result with a $device'; //Ajouter les informations du périphérique à la phrase si device n’est pas null
}
return result;
}
void main() {
// Omettre le troisième paramètre optionnel
String res1 = say('Bob', 'Howdy');
print(res1);
// Transmettre le troisième paramètre positionnel optionnel
String res2 = say('Bob', 'Howdy', 'smoke signal');
print(res2);
// Transmettre manuellement null au paramètre optionnel
String res3 = say('Alice', 'Hi', null);
print(res3);
}
Langage du code : Dart (dart)
Définir une valeur par défaut :
String say(String from, String msg, [String device = 'carrier pigeon']) {
return '$from says $msg with a $device';
}
assert(say('Bob', 'Howdy') == 'Bob says Howdy with a carrier pigeon');
Langage du code : Dart (dart)
Exemple complet
// Paramètre positionnel optionnel avec valeur par défaut carrier pigeon (pigeon voyageur)
String say(String from, String msg, [String device = 'carrier pigeon']) {
return '$from says $msg with a $device';
}
void main() {
// Omettre le troisième paramètre optionnel, utilise automatiquement la valeur par défaut carrier pigeon
String res1 = say('Bob', 'Howdy');
print(res1); //Bob says Howdy with a carrier pigeon
// Transmettre un périphérique personnalisé pour remplacer la valeur par défaut
String res2 = say('Bob', 'Howdy', 'smoke signal');
print(res2); //Bob says Howdy with a smoke signal
String res3 = say('Alice', 'Hello', 'mobile phone');
print(res3); // Alice says Hello with a mobile phone
String res4 = say('Jack', 'Tom', 'website foxdevelop.com');
print(res4); // Jack says Tom with a website foxdevelop.com
}
Langage du code : Dart (dart)
Résultat d’exécution
Built firstdart:firstdart.
Bob says Howdy with a carrier pigeon
Bob says Howdy with a smoke signal
Alice says Hello with a mobile phone
Jack says Tom with a website foxdevelop.comLangage du code : JavaScript (javascript)
Fonction d’entrée main ()
Tout programme Dart doit contenir une fonction main() au niveau racine ; c’est l’unique point d’entrée du programme.
- Version basique sans paramètres
void main() {
print('Hello, welcome to foxdevelop.com!');
}
Langage du code : Dart (dart)
Hello, welcome to foxdevelop.com!Langage du code : CSS (css)
- Programme en ligne de commande recevant des arguments de lancement
// Commande d’exécution : dart run firstdart.dart 1 test
void main(List<String> arguments) {
print(arguments); // [1, test]
}
Langage du code : Dart (dart)
Utilisez la bibliothèque officielle args pour analyser des arguments de ligne de commande complexes.
Remplacez firstdart.dart ci-dessus par le nom de votre fichier Dart

Les fonctions comme objets de première classe First-class objects
1. Transmettre des fonctions en paramètres
void printElement(int element) => print(element);
var list = [1, 2, 3];
list.forEach(printElement); // Transmettre directement la fonction
Langage du code : Dart (dart)
Exemple complet
void main() {
void printElement(int element) => print(element);
var list = [1, 2, 3];
list.forEach(printElement); // Transmettre directement la fonction
}
Langage du code : Dart (dart)
Sortie
1
2
3
2. Affecter une fonction anonyme à une variable
void main() {
var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!';
print(loudify('hello')); //!!! HELLO !!!
}
Langage du code : Dart (dart)
Type de fonction Function Type
Vous pouvez déclarer explicitement le type des variables de fonction
Format : TypeRetour Function(ListeParamètres, {ParamètresNommés})
void greet(String name, {String greeting = 'Hello'}) => print('$greeting $name!');
// Déclarer une variable de type fonction
void Function(String, {String greeting}) g = greet;
g('Dash', greeting: 'Howdy');
Langage du code : Dart (dart)
Utilisez typedef pour créer des alias de type de fonction, afin d’améliorer la réutilisation et la lisibilité.
{String greeting}) → un paramètre nommé greeting de type String
void main() {
void greet(String name, {String greeting = 'Hello'}) => print('$greeting $name!');
// Déclarer une variable de type fonction
void Function(String, {String greeting}) g = greet;
g('Jack', greeting: 'Howdy');
}
Langage du code : Dart (dart)
Sortie
Howdy Jack!
Fonctions anonymes (Lambda / Closure fermeture)
Fonctions sans nom, deux syntaxes possibles :
- Syntaxe bloc (plusieurs lignes)
void main() {
const list = ['apples', 'bananas'];
var uppercaseList = list.map((item) {
return item.toUpperCase();
}).toList();
print(uppercaseList);
}
Langage du code : Dart (dart)
Dans le code ci-dessus, (item) { return item.toUpperCase(); } est une fonction anonyme (lambda)
Sortie : [APPLES, BANANAS]
- Syntaxe fléchée abrégée (expression sur une seule ligne)
void main() {
const list = ['fox', 'develop','foxdevelop.com'];
var uppercaseList = list.map((item) => item.toUpperCase()).toList();
uppercaseList.forEach((item) => print('$item: ${item.length}'));
}
Langage du code : Dart (dart)
Sortie
FOX: 3
DEVELOP: 7
FOXDEVELOP.COM: 14Langage du code : HTTP (http)
Portée lexicale Lexical scope
Dart utilise une portée lexicale statique : la portée des variables est définie par la hiérarchie des accolades du code, et une portée interne peut accéder à toutes les variables des portées externes.
bool topLevel = true;
void main() {
var insideMain = true;
void myFunction() {
var insideFunction = true;
void nestedFunction() {
var insideNestedFunction = true;
// Toutes accessibles
assert(topLevel && insideMain && insideFunction && insideNestedFunction);
}
}
}
Langage du code : Dart (dart)
Fermetures lexicales Lexical closures
Fermeture : un objet fonction peut capturer et conserver les variables de la portée externe, et y accéder même après avoir quitté la portée initiale.
Function makeAdder(int addBy) {
// Capturer la variable externe addBy
return (int i) => addBy + i;
}
void main() {
var add2 = makeAdder(2);
var add4 = makeAdder(4);
assert(add2(3) == 5);
assert(add4(3) == 7);
}
Langage du code : Dart (dart)
Analyse pas à pas du déroulement de l’exécution ci-dessus
Étape 1 : var add2 = makeAdder(2);
- Exécuter
makeAdder, transmettreaddBy = 2 - Créer une fonction anonyme :
(int i) => 2 + i - Affecter cette fonction à la variable
add2; à ce moment add2 est un objet fonction dont le corps est(int i) => 2 + i, il reçoit un entier i et retourne i+2 - L’exécution de la fonction
makeAdderse termine, mais la fonction anonyme retient durablementaddBy=2
Étape 2 : var add4 = makeAdder(4);
- Réexécuter
makeAdder, transmettreaddBy = 4 - Créer une toute nouvelle fonction anonyme totalement indépendante :
(int i) => 4 + i - Affecter à
add4, qui stocke sa propre copie deaddBy=4sans interférer avec add2. Autrement dit, addBy est enregistré séparément dans les deux objets fonction add2 et add4, l’un stocke 2, l’autre 4
- L’appel de
makeAdder(2)génère une fermeture indépendante avec une liaison unique deaddBy = 2, affectée àadd2; - L’appel de
makeAdder(4)génère une autre fermeture neuve avec une liaison unique deaddBy = 4, affectée àadd4; add2etadd4sont deux objets fonction totalement distincts, chacun stocke en privé la variableaddBycapturée sans s’influencer mutuellement.
Étape 3 : Appeler add2(3)
Exécuter la fonction interne : 2 + 3 = 5, l’assertion est valide
Étape 4 : Appeler add4(3)
Exécuter la fonction interne : 4 + 3 = 7, l’assertion est valide
Détachements de fonction Tear-offs
Lorsque vous appelez une fonction / méthode sans parenthèses, vous créez un tear-off (fermeture légère), qui remplace les lambdas anonymes écrits manuellement pour un code plus concis.
Syntaxe recommandée : il suffit de transmettre directement la fonction.
var charCodes = [68, 97, 114, 116];
var buffer = StringBuffer();
charCodes.forEach(print); // Tear-off de fonction
charCodes.forEach(buffer.write); // Tear-off de méthode
Langage du code : Dart (dart)
Syntaxe verbeuse équivalente
charCodes.forEach((code) => print(code));
charCodes.forEach((code) => buffer.write(code));
Langage du code : Dart (dart)
Vérification de l’égalité des fonctions
- Fonctions racines, méthodes statiques : l’opérateur
==renvoie vrai si les noms de fonction sont identiques ; - Méthodes d’instance : seuls les tear-offs liés à la même instance d’objet sont considérés égaux.
void foo() {}
class A {
static void bar() {}
void baz() {}
}
void main() {
var x = foo;
assert(foo == x);
x = A.bar;
assert(A.bar == x);
var v = A(), w = A(), y = w;
x = w.baz;
assert(y.baz == x); // Même instance → égaux
assert(v.baz != w.baz); // Instances différentes → non égaux
}
Langage du code : Dart (dart)
Valeurs de retour Return values
- Toutes les fonctions ont une valeur de retour : sans
returnexplicite,return null;est ajouté implicitement à la fin
foo() {}
assert(foo() == null);
Langage du code : Dart (dart)
- Retourner plusieurs valeurs : utiliser des tuples Record
(String, int) foo() {
return ('something', 42);
}
Langage du code : Dart (dart)
Accesseurs Getter & Setter
Toute lecture ou affectation de propriété revient essentiellement à appeler un getter ou un setter ; les variables classiques génèrent automatiquement des accesseurs implicites, vous pouvez aussi les définir explicitement manuellement.
Avantage : l’accès extérieur utilise uniformément .nomPropriété, vous pouvez modifier la logique interne à tout moment sans changer le code appelant externe.
String _secret = 'Hello';
// Getter pour la lecture
String get secret {
print('Appel du getter');
return _secret.toUpperCase();
}
// Setter pour l’affectation
set secret(String newMsg) {
print('Appel du setter');
if (newMsg.isNotEmpty) _secret = newMsg;
}
void main() {
print(secret); // Lecture, déclenche le getter → HELLO
secret = 'Dart is fun'; // Affectation, déclenche le setter
print(secret); // DART IS FUN
}
Langage du code : Dart (dart)
* Générateurs Generators
Génèrent des séquences paresseusement à la demande, deux types : synchrone et asynchrone, utilisent yield pour produire des valeurs.
- Générateur synchrone
sync*, retourne unIterable
Iterable<int> naturalsTo(int n) sync* {
int k = 0;
while (k < n) yield k++;
}
Langage du code : Dart (dart)
- Générateur asynchrone
async*, retourne unStream
Stream<int> asyncNaturalsTo(int n) async* {
int k = 0;
while (k < n) yield k++;
}
Langage du code : Dart (dart)
- Optimisation des générateurs récursifs
yield*(déléguer vers un autre générateur pour améliorer les performances)
Iterable<int> naturalsDownFrom(int n) sync* {
if (n > 0) {
yield n;
yield* naturalsDownFrom(n - 1);
}
}
Langage du code : Dart (dart)
Function