El operador de coalescencia nula es un operador binario que forma parte de la sintaxis de una expresión condicional básica en varios lenguajes de programación , como (en orden alfabético): C# [1] desde la versión 2.0, [2] Dart [3] desde la versión 1.12.0, [4] PHP desde la versión 7.0.0, [5] Perl desde la versión 5.10 como operador lógico definido-o , [6] PowerShell desde 7.0.0, [7] y Swift [8] como operador de coalescencia nula .
Si bien su comportamiento difiere entre implementaciones, el operador de fusión de valores nulos generalmente devuelve el resultado de su operando más a la izquierda si existe y no es null , y de lo contrario devuelve el operando más a la derecha. Este comportamiento permite definir un valor predeterminado para los casos en los que no hay un valor más específico disponible.
A diferencia del operador condicional ternario if usado como x ? x : y
, pero al igual que el operador binario Elvis usado como x ?: y
, el operador de coalescencia nula es un operador binario y por lo tanto evalúa sus operandos como máximo una vez, lo cual es significativo si la evaluación de x
tiene efectos secundarios .
Al igual que la mayoría de los lenguajes de la familia ML , ATS utiliza tipos de datos algebraicos para representar la ausencia de un valor en lugar de nulo. Un tipo de vista de datos opcional con tipado lineal podría definirse como
tipo_vista_datos option_vt ( a : t @ ype , bool ) = | None_vt ( a , falso ) | Some_vt ( a , verdadero ) de un tipo_vistadef Option_vt ( a : t @ ype ) = [ b : bool ] option_vt ( a , b )
Una función con un valor predeterminado proporcionado puede entonces hacer una coincidencia de patrón con el valor opcional para fusionarse:
fn { a : t @ ype } valor ( predeterminado : a , opt : Option_vt a ): a = caso + opt de | ~ None_vt () => predeterminado | ~ Some_vt ( x ) => x
Que se puede utilizar por ejemplo así:
valor < int > ( 42 , None_vt ) // devuelve 42 valor < int > ( 42 , Some_vt ( 7 )) // devuelve 7
Si uno quisiera definir un operador infijo:
fn { a : t @ ype } flipped_value ( opt : Option_vt a , predeterminado : a ): a = valor ( predeterminado , opt )infixr 0 ?? # definir ?? valor_volteado
Que se puede utilizar por ejemplo así:
None_vt { int } ?? 42 // devuelve 42 Some_vt { int }( 7 ) ?? 42 // devuelve 7
En Bourne Shell (y derivados), "Si el parámetro no está definido o es nulo, se sustituye la expansión de la palabra . De lo contrario, se sustituye el valor del parámetro ": [9]
#supplied_title='título suministrado' # Descomente esta línea para usar el título suministrado title = ${ provided_title :- 'Título predeterminado' } echo " $title " # imprime: Título predeterminado
En C# , el operador de coalescencia nula es ??
.
Se utiliza con mayor frecuencia para simplificar expresiones de la siguiente manera:
Posiblemente valor nulo ?? valor si nulo
Por ejemplo, si uno desea implementar algún código C# para darle a una página un título predeterminado si no hay ninguno presente, puede usar la siguiente declaración:
cadena pageTitle = providedTitle ?? "Título predeterminado" ;
En lugar del más verboso
cadena pageTitle = ( supplyTitle != null ) ? supplyTitle : "Título predeterminado" ;
o
cadena pageTitle ; si ( submittedTitle != null ) { pageTitle = submittedTitle ; } de lo contrario { pageTitle = "Título predeterminado" ; }
Las tres formas dan como resultado el mismo valor almacenado en la variable denominada pageTitle
.
suppliedTitle
Se hace referencia a él solo una vez cuando se utiliza el ??
operador y dos veces en los otros dos ejemplos de código.
El operador también se puede utilizar varias veces en la misma expresión:
devolver algún_Valor ?? algún_Valor2 ?? algún_Valor3 ;
Una vez que se asigna un valor no nulo a un número, o se alcanza el valor final (que puede ser nulo o no), la expresión se completa.
Si, por ejemplo, una variable debe cambiarse a otro valor si su valor se evalúa como nulo, desde C# 8.0 ??=
se puede utilizar el operador de asignación de coalescencia nula:
algún_Valor ??= algún_Valor2 ;
¿Cuál es una versión más concisa de:
algún_Valor = algún_Valor ?? algún_Valor2 ;
En combinación con el operador de condición nula ?.
o el operador de acceso a elementos de condición nula, ?[]
el operador de fusión de valores nulos se puede utilizar para proporcionar un valor predeterminado si un objeto o un miembro de un objeto es nulo. Por ejemplo, lo siguiente devolverá el título predeterminado si el page
objeto es nulo o page
no es nulo pero su Title
propiedad sí lo es:
cadena pageTitle = página ?. Título ?? "Título predeterminado" ;
A partir de ColdFusion 11, [10] Railo 4.1, [11] CFML admite el operador de fusión nula como una variación del operador ternario, ?:
. Es funcional y sintácticamente equivalente a su contraparte de C#, mencionada anteriormente. Ejemplo:
PosiblementeValorNulo ?: valorSiNulo
El valor nulo normalmente no se utiliza en F# para valores o variables. [12] Sin embargo, pueden aparecer valores nulos, por ejemplo, cuando se llama al código F# desde C#.
F# no tiene un operador de coalescencia nula incorporado, pero se puede definir uno como operador personalizado según sea necesario: [13]
sea (|?) lhs rhs = ( si lhs = null entonces rhs de lo contrario lhs )
Este operador personalizado se puede aplicar según el operador de coalescencia nula incorporado de C#:
deje que pageTitle = providedTitle |? "Título predeterminado"
Los valores faltantes en Apache FreeMarker normalmente causarán excepciones. Sin embargo, se pueden manejar tanto los valores faltantes como los nulos, con un valor predeterminado opcional: [14]
${ variablefaltante ! "valorpredeterminado" }
o, para dejar la salida en blanco:
${ ¡Variable faltante ! }
En general, los tipos en Haskell no pueden ser nulos. La representación de los cálculos que pueden o no devolver un resultado significativo se representa mediante el tipo genérico Maybe, definido en la biblioteca estándar [15] como
datos Quizás a = Nada | Solo a
El operador de fusión de valores nulos reemplaza los punteros nulos por un valor predeterminado. El equivalente de Haskell es una forma de extraer un valor de un Maybe proporcionando un valor predeterminado. Esta es la función fromMaybe.
fromMaybe :: a -> Maybe a -> a fromMaybe valorPredeterminado x = caso x de Nada -> valorPredeterminado Solo valor -> valor
A continuación se muestran algunos ejemplos de uso.
fromMaybe 0 ( Solo 3 ) -- devuelve 3 fromMaybe "" Nada -- devuelve ""
El operador más cercano de JavaScript??
es , el "operador de coalescencia nula", que se agregó al estándar en la 11.ª edición de ECMAScript . [16] En versiones anteriores, se podía usar a través de un complemento de Babel y en TypeScript . Evalúa su operando de la izquierda y, si el valor del resultado no es "nulo" ( null
o undefined
), toma ese valor como su resultado; de lo contrario, evalúa el operando de la derecha y toma el valor resultante como su resultado.
En el siguiente ejemplo, a
se asignará el valor de b
si el valor de b
no es null
o undefined
, en caso contrario se asignará 3.
constante a = b ?? 3 ;
Antes del operador de fusión nulo, los programadores usaban el operador lógico OR ( ||
). Pero donde ??
busca específicamente null
or undefined
, el ||
operador busca cualquier valor falsonull
: , undefined
, ""
, 0
, NaN
, y por supuesto, false
.
En el siguiente ejemplo, a
se asignará el valor de b
si el valor de b
es verdadero , de lo contrario se asignará 3.
constante a = b || 3 ;
Kotlin utiliza el ?:
operador. [17] Esta es una elección inusual de símbolo, dado que ?:
normalmente se utiliza para el operador Elvis , no para la fusión de nulos, pero se inspiró en Groovy (lenguaje de programación) donde nulo se considera falso.
val title = supplyTitle ?: "Título predeterminado"
En Obj-C , el operador de fusión nulo es ?:
. Se puede utilizar para proporcionar un valor predeterminado para las referencias nulas:
id valor = valorQuePodríaSerNulo ?: valorSiNulo ;
Esto es lo mismo que escribir
id valor = valorQuePodríaSerNulo ? valorQuePodríaSerNulo : valorSiNulo ;
En Perl (a partir de la versión 5.10), el operador es //
y el código Perl equivalente es:
$posiblemente_valor_nulo // $valor_si_es_nulo
El valor possible_null_value se evalúa como null o not-null (en la terminología de Perl, undefined odefined ). En función de la evaluación, la expresión devuelve value_if_null cuando possible_null_value es null, o possible_null_value en caso contrario. En ausencia de efectos secundarios, esto es similar a la forma en que funcionan los operadores ternarios ( declaraciones) en los lenguajes que los admiten. El código Perl anterior es equivalente al uso del operador ternario que se muestra a continuación:?:
definido ( $posiblemente_valor_nulo ) ? $posiblemente_valor_nulo : $valor_si_es_nulo
El uso más común de este operador es minimizar la cantidad de código utilizado para una comprobación nula simple.
Perl también tiene un //=
operador de asignación, donde
$a // = $b
es en gran medida equivalente a:
$a = $a // $b
||
Este operador se diferencia de los operadores y más antiguos de Perl ||=
en que considera la definición, no la verdad . Por lo tanto, se comportan de manera diferente en valores que son falsos pero están definidos, como 0 o "" (una cadena de longitud cero):
$a = 0 ; $b = 1 ; $c = $a // $b ; # $c = 0 $c = $a || $b ; # $c = 1
PHP 7.0 introdujo [18] un operador de fusión de valores nulos con la ??
sintaxis . Este verifica estrictamente si hay valores NULL o una variable/índice de matriz/propiedad inexistente. En este sentido, actúa de manera similar a la isset()
pseudofunción de PHP:
$nombre = $solicitud -> entrada [ 'nombre' ] ?? $solicitud -> consulta [ 'nombre' ] ?? 'nombre predeterminado' ;/* Equivalente a */if ( isset ( $solicitud -> entrada [ 'nombre' ])) { $nombre = $solicitud -> entrada [ 'nombre' ]; } elseif ( isset ( $solicitud -> consulta [ 'nombre' ])) { $nombre = $solicitud -> consulta [ 'nombre' ]; } else { $nombre = 'nombre predeterminado' ; }
$usuario = $this -> obtenerUsuario () ?? $this -> crearUsuarioInvitado ();/* Equivalente a */$usuario = $este -> obtenerUsuario ();si ( $usuario === null ) { $usuario = $this -> createGuestUser (); }
$pageTitle = $title ?? 'Título predeterminado' ;/* Equivalente a */$pageTitle = isset ( $title ) ? $title : 'Título predeterminado' ;
La versión 7.4 de PHP agregará el operador de asignación de coalescencia nula con la ??=
sintaxis: [19]
// Las siguientes líneas hacen lo mismo $this -> request -> data [ 'comments' ][ 'user_id' ] = $this -> request -> data [ 'comments' ][ 'user_id' ] ?? 'value' ; // En lugar de repetir variables con nombres largos, se utiliza el operador de fusión igual $this -> request -> data [ 'comments' ][ 'user_id' ] ??= 'value' ;
Python no tiene un operador de fusión nulo. Su funcionalidad se puede imitar mediante una expresión condicional:
ahora () si el tiempo es Ninguno otro tiempo
Hubo una propuesta para agregar operadores de tipo coalescente nulo en Python 3.8, pero esa propuesta ha sido pospuesta. [20]
El operador de Python or
ofrece un comportamiento relacionado, pero diferente. La diferencia es que or
también devuelve el término de la derecha si el primer término está definido, pero tiene un valor que se evalúa como False
en un contexto booleano:
42 o "algo" # devuelve 42 0 o "algo" # devuelve "algo" Falso o "algo" # devuelve "algo" "" o "algo" # devuelve "algo" [] o "algo" # devuelve "algo" dict () o "algo" # devuelve "algo" Ninguno o "algo" # devuelve "algo"
Un verdadero operador de coalescencia nula solo retornaría "something"
en el último caso y retornaría valores casi falsos ( 0
, False
, ""
, []
, dict()
) en los otros ejemplos.
Desde PowerShell 7, el ??
operador de coalescencia nula proporciona esta funcionalidad. [7]
$myVar = $null $x = $myVar ?? "algo" # asigna "algo"
Desde la versión R 4.4.0, %||%
el operador está incluido en R base (anteriormente era una característica de algunos paquetes como rlang ).
Ruby no tiene un operador de fusión de valores nulos, pero sus operadores ||
y ||=
funcionan de la misma manera, excepto en los booleanos. Los condicionales de Ruby tienen solo dos valores similares a falsos: false
y nil
(donde 'falso' no es lo mismo que 0). ||
El operador de Ruby evalúa a su primer operando cuando es similar a verdadero. En comparación, Perl/Python/Javascript, que también tienen la última propiedad, tienen otros valores similares a falsos (0 y cadena vacía), que difieren ||
de un operador de fusión de valores nulos en muchos más casos (los números y las cadenas son dos de los tipos de datos más utilizados). Esto es lo que llevó a Perl/Python/Javascript a agregar un operador separado mientras que Ruby no lo ha hecho.
Si bien no existe null
en Rust , las uniones etiquetadas se utilizan con el mismo propósito. Por ejemplo, Result<T, E>
o Option<T>
. Cualquier tipo que implemente el rasgo Try se puede desenvolver.
unwrap_or()
Tiene una función similar a la del operador de fusión nula en otros lenguajes. Alternativamente, unwrap_or_else()
se puede utilizar para utilizar el resultado de una función como valor predeterminado.
// Opción // Una opción puede ser Some(valor) o None Some ( 1 ). unwrap_or ( 0 ); // evalúa a 1 None . unwrap_or ( 0 ); // evalúa a 0 None . unwrap_or_else ( get_default ); // evalúa al resultado de llamar a la función get_default // Resultado // Un resultado puede ser Ok(valor) o Err(error) Ok ( 1 ). unwrap_or ( 0 ); // se evalúa como 1 Err ( "oh no" ). unwrap_or ( 1 ); // se evalúa como 1
En PL/SQL de Oracle , la función NVL () proporciona el mismo resultado:
NVL ( posiblemente_valor_nulo , 'valor si es nulo' );
En SQL Server / Transact-SQL existe la función ISNULL que sigue el mismo patrón de prototipo:
ISNULL ( posiblemente_valor_nulo , 'valor si es nulo' );
Se debe tener cuidado de no confundir ISNULL con IS NULL : este último sirve para evaluar si algunos contenidos están definidos como NULL o no.
El estándar ANSI SQL-92 incluye la función COALESCE implementada en Oracle , [21] SQL Server , [22] PostgreSQL , [23] SQLite [24] y MySQL . [25] La función COALESCE devuelve el primer argumento que no es nulo. Si todos los términos son nulos, devuelve nulo.
COALESCE ( posiblemente_valor_nulo [, posiblemente_valor_nulo , ... ]);
La diferencia entre ISNULL y COALESCE es que el tipo devuelto por ISNULL es el tipo del valor más a la izquierda, mientras que COALESCE devuelve el tipo del primer valor no nulo.
En Swift , el operador de fusión nulo es ??
. Se utiliza para proporcionar un valor predeterminado al desenvolver un tipo opcional :
valoropcional ?? valorSiNulo
Por ejemplo, si uno desea implementar algún código Swift para darle a una página un título predeterminado si no hay ninguno presente, puede usar la siguiente declaración:
var providedTitle : String ? = ... var pageTitle : String = providedTitle ?? "Título predeterminado"
En lugar del más verboso
var pageTitle : String = ( supplyTitle != nil ) ? supplyTitle ! : "Título predeterminado" ;
En VB.NET, el operador/palabra clave If
[26] logra el efecto de operador de coalescencia nula.
Dim pageTitle = If ( submittedTitle , "Título predeterminado" )
que es una forma más concisa de utilizar su variación
Dim pageTitle = If ( suministradoTítulo <> Nada , suministradoTítulo , "Título predeterminado" )