En la programación orientada a objetos , el operador de navegación segura (también conocido como operador de encadenamiento opcional , operador de llamada segura , operador condicional nulo ) es un operador binario que devuelve nulo si su primer argumento es nulo; de lo contrario, realiza una operación de eliminación de referencias según lo especificado por el segundo argumento (normalmente un acceso a un miembro de objeto, un índice de matriz o una invocación lambda).
Se utiliza para evitar verificaciones y asignaciones nulas explícitas secuenciales y reemplazarlas con encadenamiento de método / propiedad. En lenguajes de programación donde el operador de navegación (por ejemplo, ".") Conduce a un error si se aplica a un objeto nulo, el operador de navegación segura detiene la evaluación de una cadena de método / campo y devuelve nulo como valor de la expresión de la cadena. Actualmente es compatible con lenguajes como Apex , [1] Apache Groovy , [2] Swift , [3] Ruby , [4] C # , [5] Kotlin , [6] CoffeeScript , Scala , [7] Dart [8]y otros. Actualmente no existe una convención de nomenclatura común para este operador, pero operador de navegación segura es el término más utilizado.
La principal ventaja de utilizar este operador es que evita la pirámide de la fatalidad . En lugar de escribir varios mensajes de correo electrónico anidados if
, los programadores pueden usar el encadenamiento habitual, pero agregar símbolos de interrogación antes de los puntos (u otros caracteres utilizados para el encadenamiento).
Si bien el operador de navegación segura y el operador de fusión nula son operadores conscientes de nulos , son operacionalmente diferentes.
Ejemplos de
Apéndice
Ejemplos de operadores de navegación segura: [9]
una [ x ]? . aMethod (). aField // Evalúa como nulo si a [x] == nulo a [ x ] . unMétodo () ? . aField // devuelve nulo si un [x] .aMethod () se evalúa como nulo String profileUrl = user . getProfileUrl () ? . toExternalForm (); return [ SELECCIONAR Nombre DE Cuenta DONDE Id = : accId ]? . Nombre ;
C#
C # 6.0 y superior tienen ?.
, el operador de acceso de miembro condicional nulo (que también es llamado el operador de Elvis por Microsoft y no debe confundirse con el uso general del término operador de Elvis , cuyo equivalente en C # es ??
, el operador de fusión nula ) y ?[]
el operador de acceso al elemento condicional nulo , que realiza una llamada de seguridad nula de un descriptor de acceso get . Si el tipo del resultado del acceso de miembro es un tipo de valor , el tipo del resultado de un acceso condicional nulo de ese miembro es una versión anulable de ese tipo de valor . [10]
El siguiente ejemplo recupera el nombre del autor del primer artículo en una matriz de artículos (siempre que cada artículo tenga un Author
miembro y que cada autor tenga un Name
miembro), y da como resultado null
si la matriz es null
, si su primer elemento es null
, si el Author
miembro de ese artículo es null
, o si el Name
miembro de ese autor lo es null
. Tenga en cuenta que IndexOutOfRangeException
todavía se lanza si la matriz no es nula pero está vacía (es decir, de longitud cero).
var nombre = artículos ? [ 0 ] ?. Autor ?. Nombre ;
Llamar a un lambda requiere callback?.Invoke()
, ya que no hay una invocación condicional nula ( callback?()
no está permitida).
var resultado = devolución de llamada ?. Invocar ( args );
Clojure
Clojure no tiene operadores verdaderos en el sentido en que otros lenguajes lo usan, pero como interopera con Java, y tiene que realizar la navegación de objetos cuando lo hace, la macro some->
[11] se puede usar para realizar una navegación segura.
( Algu-> artículo .author .name )
CoffeeScript
Operador existencial: [12]
zip = lotería . drawWinner ? (). dirección ? . código postal
Dardo
Operador de acceso de miembros condicional: [8]
var nombre = artículo ? . autor ? . nombre
Groovy
Operador de navegación segura y operador de índice seguro: [2] [13]
def nombre = artículo ?. autores ? [ 0 ]. nombre
Gosu
Operador de invocación segura nula: [14]
var nombre = artículo ?. autor ?. nombre
El operador de invocación de seguridad nula no es necesario para los atributos de clase declarados como Propiedades de Gosu:
class Foo { var _bar : String as Bar }var foo : Foo = null// lo siguiente se evaluará como nulo y no devolverá una NullPointerException var bar = foo . Bar
JavaScript
Agregado en ECMAScript 2020, el operador de encadenamiento opcional proporciona una forma de simplificar el acceso a valores a través de objetos conectados cuando es posible que una referencia o función no esté definida o sea nula . [15]
const nombre = artículo ? . autores ? . [ 0 ] ? . nombre const resultado = devolución de llamada ? . ()
Cortocircuita toda la cadena de llamadas en su lado derecho: en el siguiente ejemplo, no se "accede" a la barra .
nulo ? . foo . bar
Kotlin
Operador de llamada segura: [6]
val nombre = artículo ?. autor ?. nombre
C objetivo
La sintaxis de navegación normal se puede utilizar en la mayoría de los casos sin tener en cuenta los NULL, ya que los mensajes subyacentes, cuando se envían a NULL, se descartan sin efectos nocivos.
NSString * nombre = artículo . autor [ 0 ]. nombrar ;
Rubí
Ruby es compatible con el &.
operador de navegación segura (también conocido como el operador solitario ) desde la versión 2.3.0: [4]
nombre = artículo &. autor &. nombre
Rápido
Operador de encadenamiento opcional, operador de subíndice [3] y llamada:
dejar nombre = artículo ?. autores ? [ 0 ]. name let result = protocolVar ?. ¿ Requisito opcional ? ()
PHP
El operador seguro nulo fue aceptado para PHP 8: [16]
$ nombre = $ artículo ? -> autor ? -> nombre ;
Pitón
El operador de navegación segura no es compatible con Python. Se propuso su inclusión con la siguiente sintaxis: [17]
# Sintaxis propuesta, que todavía no forma parte del lenguaje: nombre = artículo ? . autor ? . nombre
Raku (Perl 6)
Llamada al método seguro: [18]
mi $ nombre = $ artículo .? autor .? nombrar ;
Mecanografiado
El operador de encadenamiento opcional se incluyó en la versión 3.7 de TypeScript: [19]
deje x = foo ? . bar ? . baz ();
Cristal
Crystal admite el try
método de navegación segura [20]
nombre = artículo . prueba &. autor . prueba &. nombre
Oxido
Rust apoya a los operadores ?
y try!{}
para las estructuras que implementan el Try
rasgo. [21]
// El método preferido para devolver rápidamente los errores fn write_to_file_question () -> Result < (), MyError > { let mut file = File :: create ( "my_best_friends.txt" ) ? ; archivo . write_all ( b "Esta es una lista de mis mejores amigos." ) ? ; Ok (())}// El método anterior para devolver rápidamente los errores fn write_to_file_using_try () -> Result < (), MyError > { ¡ Deje que mut file = r # intente ! ( Archivo :: crear ( "my_best_friends.txt" )); r # ¡ prueba ! ( file . write_all ( b "Esta es una lista de mis mejores amigos." )); Ok (())}
Scala
El operador de seguridad nula en Scala lo proporciona la biblioteca Dsl.scala. [22]
val nombre = artículo .?. autor .?. nombre : @ ?
La @ ?
anotación se puede utilizar para denotar un valor que acepta valores NULL.
clase de caso Árbol ( izquierda : Árbol @ ? = nulo , derecha : Árbol @ ? = nulo , valor : Cadena @ ? = nulo )val root : Árbol @ ? = Árbol ( izquierda = Árbol ( izquierda = Árbol ( valor = "izquierda-izquierda" ), derecha = Árbol ( valor = "izquierda-derecha" ) ), derecha = Árbol ( valor = "derecha" ) )
Lo normal .
en Scala no es seguro para nulos cuando se realiza un método en un null
valor.
una [ NullPointerException ] debería ser lanzada por { root . bien . a la izquierda . bien . valor // root.right.left es nulo! }
La excepción se puede evitar utilizando el ?
operador en el valor que acepta valores NULL en su lugar:
raíz .?. ¿verdad ?. izquierda .?. el valor debe ser ( nulo )
La expresión completa es null
si uno de ?
se realiza en un null
valor.
El límite de un null
operador seguro ?
es la expresión envolvente más cercana cuyo tipo se anota como @ ?
.
( "Hola" + ( "mundo" + raíz .?. Derecha .?. Izquierda .?. Valor )) debe ser ( "Hola mundo nulo" ) ( "Hola" + (( "mundo" + raíz .?. Derecha .?. left .?. value .?) : @ ? )) debe ser ( "Hello null" ) (( "Hello" + ( "world" + root .?. right .?. left .?. value .? )) : @ ? ) debe ser ( nulo )
Visual Basic .NET
Visual Basic 14 y versiones posteriores tienen ?.
(el operador de acceso a miembros condicional nulo ) y ?()
(el operador de índice condicional nulo ), similar a C #. Tienen el mismo comportamiento que los operadores equivalentes en C #. [23]
La siguiente declaración se comporta de manera idéntica al ejemplo de C # anterior.
Dim name = artículos ? ( 0 ) ? . Autor ? . Nombre
Ver también
Referencias
- ^ "Operador de navegación segura | Guía para desarrolladores de Apex | Desarrolladores de Salesforce" . developer.salesforce.com . Consultado el 13 de octubre de 2020 .
- ^ a b "Encadenamiento opcional" . Consultado el 28 de enero de 2016 .
- ^ a b "Ruby 2.3.0 lanzado" . Consultado el 28 de enero de 2016 .
- ^ "Operadores condicionales nulos (C # y Visual Basic)" . Consultado el 28 de enero de 2016 .
- ^ a b "Seguridad nula" . Consultado el 28 de enero de 2016 .
- ^ "NullSafe: Kotlin / Groovy sabor null-safe? Operador ahora en Scala" . Usuarios de Scala . 2018-09-12 . Consultado el 3 de junio de 2019 .
- ^ a b "Otros operadores" . Un recorrido por el idioma Dart . Consultado el 8 de enero de 2020 .
- ^ "Notas de la versión de Salesforce Winter 21" . Salesforce . Consultado el 13 de octubre de 2020 .
- ^ "Operadores de acceso a miembros (referencia de C #)" . Microsoft Docs . Microsoft . Consultado el 29 de agosto de 2019 .
- ^ "Guía de macros de subprocesos" . Consultado el 7 de junio de 2019 .
- ^ "El Operador Existencial" . Consultado el 15 de junio de 2017 .
- ^ "8.5. Operador de índice seguro" . Consultado el 25 de septiembre de 2020 .
- ^ "El lenguaje de programación Gosu" . Consultado el 18 de diciembre de 2018 .
- ^ https://tc39.es/proposal-optional-chaining/
- ^ "PHP: rfc: nullsafe_operator" . wiki.php.net . Consultado el 1 de octubre de 2020 .
- ^ "PEP 505 - Operadores sin conocimiento" . Consultado el 27 de agosto de 2018 .
- ^ "Operadores de Raku" . Consultado el 28 de junio de 2016 .
- ^ "Mecanografiado 3.7" . Consultado el 6 de noviembre de 2019 .
- ^ "Crystal API: Object # try" .
- ^ "Trait std :: ops :: Try" . Consultado el 26 de febrero de 2019 .
- ^ Un marco para crear lenguajes específicos de dominio integrados en Scala: ThoughtWorksInc / Dsl.scala , ThoughtWorks Inc., 2019-06-03 , consultado el 2019-06-03
- ^ "?. y? () operadores condicionales nulos (Visual Basic)" . Microsoft Docs . Microsoft . Consultado el 29 de agosto de 2019 .
enlaces externos
- PEP 505 , discutiendo la posibilidad de operadores de navegación seguros para Python