Operador de navegação segura - Safe navigation operator
Na programação orientada a objetos , o operador de navegação segura (também conhecido como operador de encadeamento opcional , operador de chamada segura , operador de condição nula ) é um operador binário que retorna nulo se seu primeiro argumento for nulo; caso contrário, ele executa uma operação de desreferenciamento conforme especificado pelo segundo argumento (normalmente um acesso de membro de objeto, índice de array ou invocação lambda).
É usado para evitar verificações e atribuições nulas explícitas sequenciais e substituí-las por encadeamento de método / propriedade. Em linguagens de programação em que o operador de navegação (por exemplo, ".") Leva a um erro se aplicado a um objeto nulo, o operador de navegação segura interrompe a avaliação de uma cadeia de método / campo e retorna nulo como o valor da expressão da cadeia. Foi usado pela primeira vez pelo Groovy 1.0 em 2007 e atualmente é compatível com linguagens como C # , Swift , TypeScript , Ruby , Kotlin , Rust e outras. Atualmente, não existe uma convenção de nomenclatura comum para este operador, mas operador de navegação segura é o termo mais amplamente usado.
A principal vantagem de usar esse operador é que ele evita a pirâmide da desgraça . Em vez de escrever vários if
s aninhados , os programadores podem apenas usar o encadeamento usual, mas adicionar símbolos de ponto de interrogação antes dos pontos (ou outros caracteres usados para encadeamento).
Embora o operador de navegação segura e o operador de coalescência nula sejam ambos operadores nulos , eles são operacionalmente diferentes.
Exemplos
Ápice
Exemplos de operador de navegação segura:
a[x]?.aMethod().aField // Evaluates to null if a[x] == null
a[x].aMethod()?.aField // returns null if a[x].aMethod() evaluates to null
String profileUrl = user.getProfileUrl()?.toExternalForm();
return [SELECT Name FROM Account WHERE Id = :accId]?.Name;
C #
C # 6.0 e superior têm ?.
, o operador de acesso de membro condicional nulo (que também é chamado de operador Elvis pela Microsoft e não deve ser confundido com o uso geral do termo operador Elvis , cujo equivalente em C # é ??
o operador de coalescência nulo ) e ?[]
, o operador de acesso de elemento condicional nulo , que executa uma chamada segura de um indexador get acessador . Se o tipo de resultado do acesso do membro for um tipo de valor , o tipo do resultado de um acesso condicional nulo desse membro será uma versão anulável desse tipo de valor .
O exemplo a seguir recupera o nome do autor do primeiro artigo em uma matriz de artigos (desde que cada artigo tenha um Author
membro e cada autor tenha um Name
membro) e resulta em null
se a matriz for null
, se seu primeiro elemento for null
, se o Author
membro desse artigo é null
, ou se o Name
membro desse autor é null
. Observe que um IndexOutOfRangeException
ainda é lançado se a matriz não for nula, mas vazia (ou seja, comprimento zero).
var name = articles?[0]?.Author?.Name;
Chamar um lambda requer callback?.Invoke()
, pois não há invocação condicional nula ( callback?()
não é permitido).
var result = callback?.Invoke(args);
Clojure
Clojure não tem operadores verdadeiros no sentido em que outras linguagens o usam, mas como ele funciona com Java e tem que realizar navegação de objeto quando o faz, a some->
macro pode ser usada para realizar navegação segura.
(some-> article .author .name)
CoffeeScript
Operador existencial:
zip = lottery.drawWinner?().address?.zipcode
Cristal
Crystal suporta o try
método de navegação segura
name = article.try &.author.try &.name
Dardo
Operador de acesso condicional de membro:
var name = article?.author?.name
Gosu
Operador de invocação segura nula:
var name = article?.author?.name
O operador de invocação null-safe não é necessário para atributos de classe declarados como Propriedades Gosu:
class Foo {
var _bar: String as Bar
}
var foo: Foo = null
// the below will evaluate to null and not return a NullPointerException
var bar = foo.Bar
Groovy
Operador de navegação segura e operador de índice seguro:
def name = article?.authors?[0].name
JavaScript
Adicionado no ECMAScript 2020, o operador de encadeamento opcional fornece uma maneira de simplificar o acesso a valores por meio de objetos conectados quando é possível que uma referência ou função seja indefinida ou nula .
const name = article?.authors?.[0]?.name
const result = callback?.()
Ele causa um curto-circuito em toda a cadeia de chamadas do lado direito: no exemplo a seguir, a barra não é "acessada".
null?.foo.bar
Kotlin
Operadora de chamada segura:
val name = article?.author?.name
Objective-C
A sintaxe de navegação normal pode ser usada na maioria dos casos sem considerar NULLs, já que as mensagens subjacentes, quando enviadas para NULL, são descartadas sem nenhum efeito prejudicial.
NSString *name = article.author[0].name;
PHP
O operador seguro nulo foi aceito para PHP 8:
$name = $article?->author?->name;
Pitão
O operador de navegação segura não é compatível com Python. Foi proposto para inclusão com a seguinte sintaxe:
# Proposed syntax, not yet part of the language:
name = article?.author?.name
Raku (Perl 6)
Chamada de método seguro:
my $name = $article.?author.?name;
Rubi
Ruby oferece suporte ao &.
operador de navegação segura (também conhecido como operador solitário ) desde a versão 2.3.0:
name = article&.author&.name
Ferrugem
Rust suporta os operadores ?
e try!{}
para estruturas que implementam a Try
característica.
// The preferred method of quick returning Errors
fn write_to_file_question() -> Result<(), MyError> {
let mut file = File::create("my_best_friends.txt")?;
file.write_all(b"This is a list of my best friends.")?;
Ok(())
}
// The previous method of quick returning Errors
fn write_to_file_using_try() -> Result<(), MyError> {
let mut file = r#try!(File::create("my_best_friends.txt"));
r#try!(file.write_all(b"This is a list of my best friends."));
Ok(())
}
Scala
O operador null-safe em Scala é fornecido pela biblioteca Dsl.scala.
val name = article.?.author.?.name : @ ?
A @ ?
anotação pode ser usada para denotar um valor anulável.
case class Tree(left: Tree @ ? = null, right: Tree @ ? = null, value: String @ ? = null)
val root: Tree @ ? = Tree(
left = Tree(
left = Tree(value = "left-left"),
right = Tree(value = "left-right")
),
right = Tree(value = "right")
)
O normal .
em Scala não é seguro para nulos, ao executar um método em um null
valor.
a[NullPointerException] should be thrownBy {
root.right.left.right.value // root.right.left is null!
}
A exceção pode ser evitada usando o ?
operador no valor anulável em vez disso:
root.?.right.?.left.?.value should be(null)
A expressão inteira é null
se um dos ?
for executado em um null
valor.
O limite de um null
operador seguro ?
é a expressão envolvente mais próxima cujo tipo é anotado como @ ?
.
("Hello " + ("world " + root.?.right.?.left.?.value)) should be("Hello world null")
("Hello " + (("world " + root.?.right.?.left.?.value.?): @ ?)) should be("Hello null")
(("Hello " + ("world " + root.?.right.?.left.?.value.?)): @ ?) should be(null)
Rápido
Operador de encadeamento opcional, operador subscrito e chamada:
let name = article?.authors?[0].name
let result = protocolVar?.optionalRequirement?()
TypeScript
O operador de encadeamento opcional foi incluído na versão Typescript 3.7:
let x = foo?.bar?.[0]?.baz();
Visual Basic .NET
Visual Basic 14 e acima têm ?.
(o operador de acesso de membro condicional nulo ) e ?()
(o operador de índice condicional nulo ), semelhante ao C #. Eles têm o mesmo comportamento que os operadores equivalentes em C #.
A instrução a seguir se comporta de forma idêntica ao exemplo C # acima.
Dim name = articles?(0)?.Author?.Name
Veja também
Referências
links externos
- PEP 505 , discutindo a possibilidade de operadores de navegação segura para Python