Opérateur de fusion nulle
From Wikipedia, the free encyclopedia
L'opérateur de fusion nulle est un opérateur binaire qui fait partie de la syntaxe des expressions conditionnelles de base dans plusieurs langages de programmation, tels que (par ordre alphabétique) : C#[1] depuis la version 2.0[2], Dart[3] depuis la version 1.12.0[4], PHP depuis la version 7.0.0[5], Perl depuis la version 5.10 en tant que opérateur OU logique[6], PowerShell depuis la version 7.0.0[7], et Swift[8] en tant qu'opérateur de fusion nulle. On l'écrit le plus souvent x ?? y, mais cela varie selon les langages de programmation.
Bien que son comportement varie selon les implémentations, l'opérateur de fusion nulle renvoie généralement le résultat de l'opérande situé le plus à gauche s'il existe et n'est pas nul (zh) ; dans le cas contraire, il renvoie l'opérande situé le plus à droite. Ce comportement permet de définir une valeur par défaut pour les cas où aucune valeur plus spécifique n'est disponible.
Tout comme l'opérateur binaire Elvis (en), généralement noté x ?: y, l'opérateur de fusion nulle est un opérateur à court-circuit (de) ; il n'évalue donc pas le deuxième opérande si sa valeur n'est pas utilisée, ce qui est important lorsque son évaluation entraîne des effets de bords.
Bourne shell
Dans le Bourne shell (et ses dérivés), le paramètre Si n'est pas défini ou est nul, c'est le résultat de l'expansion de word qui est substitué. Sinon, c'est la valeur de paramètre qui est substituée[9]:
#supplied_title='supplied title' # Uncomment this line to use the supplied title
title=${supplied_title:-'Default title'}
echo "$title" # prints: Default title
C#
En C#, l'opérateur de fusion nulle est ??.
Il est le plus souvent utilisé pour simplifier des expressions comme suit :
possiblyNullValue ?? valueIfNull
Par exemple, si l'on souhaite implémenter du code C# pour attribuer un titre par défaut à une page lorsqu'il n'y en a pas, on peut utiliser l'instruction suivante :
string pageTitle = suppliedTitle ?? "Default Title";
au lieu de la version plus détaillée
string pageTitle = (suppliedTitle != null) ? suppliedTitle : "Default Title";
ou
string pageTitle;
if (suppliedTitle != null)
{
pageTitle = suppliedTitle;
}
else
{
pageTitle = "Default Title";
}
Ces trois formules permettent d'enregistrer la même valeur dans la variable nommée pageTitle.
suppliedTitle n'est référencé qu'une seule fois lors de l'utilisation de l'opérateur ??, et deux fois dans les deux autres exemples de code.
Cet opérateur peut également être utilisé plusieurs fois dans la même expression :
return some_Value ?? some_Value2 ?? some_Value3;
Dès qu'une valeur non nulle est attribuée à number, ou que celui-ci atteint sa valeur finale (qui peut être nulle ou non), l'expression est évaluée.
Si, par exemple, une variable doit prendre une autre valeur lorsque sa valeur est nulle, depuis C# 8.0, l'opérateur de fusion nulle ??= peut être utilisé :
some_Value ??= some_Value2;
Ce qui est une version plus concise de :
some_Value = some_Value ?? some_Value2;
En combinaison avec l'opérateur conditionnel null (zh) ?. ou l'opérateur d'accès à un élément conditionnel nul ?[] l'opérateur de fusion nulle permet de fournir une valeur par défaut si un objet ou un membre d'un objet est nul. Par exemple, le code suivant renverra le titre par défaut si l'objet page est nul ou si page n'est pas nul, mais sa propriété Title l'est :
string pageTitle = page?.Title ?? "Default Title";
CFML
À partir de ColdFusion 11[10] et Railo (en) 4.1[11], CFML prend en charge l'opérateur de fusion nulle comme une variante de l'opérateur ternaire ?:. Elle est équivalente, tant sur le plan fonctionnel que syntaxique, à son équivalent en C# présenté ci-dessus. Exemple :
possiblyNullValue ?: valueIfNull
FreeMarker
Les valeurs manquantes dans Apache FreeMarker provoquent généralement des exceptions. Cependant, il est possible de gérer à la fois les valeurs manquantes et les valeurs nulles, en utilisant une valeur par défaut facultative[12]:
${missingVariable!"defaultValue"}
ou, pour laisser le champ de sortie vide :
${missingVariable!}
JavaScript
L'opérateur le plus proche en JavaScript est ??, l'opérateur de fusion nulle, qui a été ajouté à la norme dans la 11e édition d'ECMAScript[13]. Dans les versions précédentes, il pouvait être utilisé via un plugin Babel (en), ainsi que dans TypeScript. Il évalue son opérande de gauche et, si la valeur obtenue n'est « pas » « nulle » (null ou undefined), prend cette valeur comme résultat ; sinon, elle évalue l'opérande de droite et prend la valeur obtenue comme résultat.
Dans l'exemple suivant, a se verra attribuer la valeur de b si la valeur de b n'est pas null ou undefined, sinon, on lui attribuera la valeur 3.
const a = b ?? 3;
Avant l'apparition de l'opérateur de fusion nulle, les programmeurs utilisaient l'opérateur logique OR (||). Mais où ?? recherche spécifiquement null ou undefined, l'opérateur || recherche toute valeur fausse : null, undefined, "", 0, NaN, et bien sûr, false.
Dans l'exemple suivant, a se verra attribuer la valeur de b si la valeur de b est vraie, sinon, la valeur 3 lui sera attribuée.
const a = b || 3;
Kotlin
Kotlin utilise l'opérateur ?:[14]. C'est un choix de symbole inhabituel, étant donné que ?: est généralement utilisé pour l'opérateur Elvis (en), et non pour la fusion des valeurs nulles, mais il s'inspire du langage de programmation Groovy, dans lequel la valeur null est considérée comme fausse.
val title = suppliedTitle ?: "Default title"
Objective-C
En Obj-C, l'opérateur de fusion nulle est ?:. Elle peut être utilisée pour fournir une valeur par défaut aux références nil :
id value = valueThatMightBeNil ?: valueIfNil;
Cela revient à écrire
id value = valueThatMightBeNil ? valueThatMightBeNil : valueIfNil;
Perl
En Perl (à partir de la version 5.10), l'opérateur est // et le code Perl équivalent est :
$possibly_null_value // $value_if_null
La valeur possiblement nulle est évaluée comme nulle ou non-nulle (dans la terminologie Perl, undefined ou defined). En fonction de cette évaluation, l'expression renvoie soit value_if_null lorsque possibly_null_value est nulle, soit possibly_null_value dans le cas contraire. En l'absence d'effets de bords, cela s'apparente au fonctionnement des opérateurs ternaires (?:) dans les langages qui les prennent en charge. Le code Perl ci-dessus équivaut à l'utilisation de l'opérateur ternaire ci-dessous :
defined($possibly_null_value) ? $possibly_null_value : $value_if_null
Cet opérateur sert principalement à réduire la quantité de code nécessaire pour effectuer une simple vérification de nullité.
Perl dispose également d'un opérateur d'affectation //=, où
$a //= $b
correspond en grande partie à :
$a = $a // $b
Cet opérateur diffère des anciens opérateurs de Perl || et ||= en ce sens qu'ils prennent en compte la définition, et non la vérité. Ils se comportent donc différemment avec des valeurs fausses mais définies, telles que 0 ou "" (une chaîne de longueur nulle) :
$a = 0;
$b = 1;
$c = $a // $b; # $c = 0
$c = $a || $b; # $c = 1
PHP
PHP 7.0 introduit[15] un opérateur de fusion nulle avec la syntaxe ??. Cette vérification recherche strictement les valeurs NULL ou les variables, indices de tableau ou propriétés inexistants. À cet égard, elle fonctionne de manière similaire à la pseudo-fonction de PHP isset() :
$name = $request->input['name'] ?? $request->query['name'] ?? 'default name';
/* Equivalent to */
if (isset($request->input['name'])) {
$name = $request->input['name'];
} elseif (isset($request->query['name'])) {
$name = $request->query['name'];
} else {
$name = 'default name';
}
$user = $this->getUser() ?? $this->createGuestUser();
/* Equivalent to */
$user = $this->getUser();
if ($user === null) {
$user = $this->createGuestUser();
}
$pageTitle = $title ?? 'Default Title';
/* Equivalent to */
$pageTitle = isset($title) ? $title : 'Default Title';
La version 7.4 de PHP introduit l'opérateur d'affectation avec fusion des valeurs nulles, dont la syntaxe est la suivante ??=[16]:
// The following lines are doing the same
$this->request->data['comments']['user_id'] = $this->request->data['comments']['user_id'] ?? 'value';
// Instead of repeating variables with long names, the equal coalesce operator is used
$this->request->data['comments']['user_id'] ??= 'value';
PowerShell
Depuis PowerShell 7, l'opérateur de fusion nulle ?? permet cette fonctionnalité[7].
$myVar = $null
$x = $myVar ?? "something" # assigns "something"
R
Depuis la version 4.4.0 de R, l'opérateur %||% est inclus dans R de base (auparavant, cette fonctionnalité était disponible dans certains paquets tels que rlang)[17].
> NULL %||% 2
[1] 2
Rust
Même s'il n'y a pas null dans Rust, les types sommes sont utilisées dans le même but. Par exemple, Result<T, E> ou Option<T>.
Tout type implémentant le trait Try peut être déballé.
unwrap_or() remplit une fonction similaire à celle de l'opérateur de fusion de valeurs nulles dans d'autres langages. Sinon, unwrap_or_else() peut être utilisé pour utiliser le résultat d'une fonction comme valeur par défaut.
// Option
// An Option can be either Some(value) or None
Some(1).unwrap_or(0); // evaluates to 1
None.unwrap_or(0); // evaluates to 0
None.unwrap_or_else(get_default); // evaluates to the result of calling the function get_default
// Result
// A Result can be either Ok(value) or Err(error)
Ok(1).unwrap_or(0); // evaluates to 1
Err("oh no").unwrap_or(1); // evaluates to 1
SQL
Dans le PL/SQL d'Oracle, la fonction NVL () (en) donne le même résultat :
NVL(possibly_null_value, 'value if null');
Dans SQL Server/Transact-SQL, il existe la fonction ISNULL qui suit le même modèle de prototype :
ISNULL(possibly_null_value, 'value if null');
Il faut veiller à ne pas confondre ISNULL et IS NULL : cette dernière fonction sert à déterminer si une valeur est définie comme NULL ou non.
La norme ANSI SQL-92 inclut la fonction COALESCE implémentée dans Oracle[18], SQL Server[19], PostgreSQL[20], SQLite[21] et MySQL[22]. La fonction COALESCE renvoie le premier argument qui n'est pas nul. Si tous les arguments sont nuls, elle renvoie la valeur null.
COALESCE(possibly_null_value[, possibly_null_value, ...]);
La différence entre ISNULL et COALESCE réside dans le fait que le type renvoyé par ISNULL correspond au type de la valeur la plus à gauche, tandis que COALESCE renvoie le type de la première valeur non nulle.
Swift
Dans Swift, l'opérateur de fusion nulle est ??. Elle sert à fournir une valeur par défaut lors du déballage d'un type optionnel (es) :
optionalValue ?? valueIfNil
Par exemple, si l'on souhaite implémenter du code Swift pour attribuer un titre par défaut à une page lorsqu'il n'y en a pas, on peut utiliser l'instruction suivante :
var suppliedTitle: String? = ...
var pageTitle: String = suppliedTitle ?? "Default Title"
au lieu de la version plus détaillée
var pageTitle: String = (suppliedTitle != nil) ? suppliedTitle! : "Default Title";
Voir aussi
Références
- ↑ « ?? and ??= operators - the null-coalescing operators », sur Microsoft Learn (en),
- ↑ « ECMA-334, 3rd edition, June 2005 », sur ecma-international.org, Ecma International, , p. 63
- ↑ « Conditional expression », sur Dart
- ↑ « Dart SDK Changelog, 1.12.0 », sur GitHub,
- ↑ « PHP 7.0.0 Released », sur PHP,
- ↑ « perlop - Perl expressions: operators, precedence, string literals », sur Perldoc Browser (en)
- 1 2 (en-US) « PowerShell 7 Preview 5 », sur PowerShell, (consulté le )
- ↑ « The Swift Programming Language (Swift 5): Basic Operators: Nil-Coalescing Operator », sur docs.swift.org
- ↑ « Bash man page »
- ↑ « Elvis operator », sur wikidocs.adobe.com
- ↑ « [RAILO-2195] add support for the Elvis Operator », sur JBoss Issue Tracker
- ↑ « Expressions », sur Apache FreeMarker Manual,
- ↑ « ECMAScript 2020 Language Specification », sur Ecma International,
- ↑ « Null safety »
- ↑ « PHP: rfc:isset_ternary » (consulté le )
- ↑ Midori Kocak, « PHP RFC: Null Coalescing Assignment Operator », sur PHP.net (consulté le )
- ↑ Russ Hyde, « What’s new in R 4.4.0? », sur Jumping Rivers,
- ↑ « Database SQL Language Reference », sur docs.oracle.com
- ↑ « COALESCE (SQL Server Compact) », sur technet.microsoft.com,
- ↑ « PostgreSQL: Documentation: 9.1: Conditional Expressions », sur www.postgresql.org,
- ↑ « SQLite Query Language: Core Functions », sur www.sqlite.org
- ↑ « MySQL :: MySQL 5.5 Reference Manual :: 12.3.2 Comparison Functions and Operators », sur dev.mysql.com