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 ifs 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 Authormembro e cada autor tenha um Namemembro) e resulta em nullse a matriz for null, se seu primeiro elemento for null, se o Authormembro desse artigo é null, ou se o Namemembro desse autor é null. Observe que um IndexOutOfRangeExceptionainda é 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 trymé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 Trycaracterí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 nullvalor.

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 é nullse um dos ?for executado em um nullvalor.

O limite de um nulloperador 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