Operador de coalescência nula - Null coalescing operator

O operador null coalescing (chamado de operador Logical Defined-Or em Perl ) é um operador binário que faz parte da sintaxe de uma expressão condicional básica em várias linguagens de programação , incluindo C # , PowerShell a partir da versão 7.0.0, Perl a partir da versão 5.10, Swift e PHP 7.0.0. Embora seu comportamento seja diferente entre as implementações, o operador de coalescência nulo geralmente retorna o resultado de seu operando mais à esquerda se ele existe e não é nulo e, caso contrário, retorna o operando mais à direita. Este comportamento permite que um valor padrão seja definido para os casos em que um valor mais específico não está disponível.

Em contraste com o operador condicional ternário usado como x ? x : y, mas como o operador binário Elvis usado como x ?: y, o operador de coalescência nulo é um operador binário e, portanto, avalia seus operandos no máximo uma vez, o que é significativo se a avaliação de xtiver efeitos colaterais .

Exemplos por linguagens

Bash

Em Bash "Se o parâmetro não for definido ou for nulo, a expansão da palavra será substituída. Caso contrário, o valor do parâmetro será substituído":

#supplied_title='supplied title' # Uncomment this line to use the supplied title
title=${supplied_title:-'Default title'}
echo "$title" # prints: Default title

C #

Em C # , o operador de coalescência nulo é ??.

É mais frequentemente usado para simplificar expressões da seguinte maneira:

possiblyNullValue ?? valueIfNull

Por exemplo, se alguém deseja implementar algum código C # para dar a uma página um título padrão se nenhum estiver presente, pode-se usar a seguinte instrução:

string pageTitle = suppliedTitle ?? "Default Title";

em vez do mais prolixo

string pageTitle = (suppliedTitle != null) ? suppliedTitle : "Default Title";

ou

string pageTitle;

if (suppliedTitle != null)
{
    pageTitle = suppliedTitle;
}
else
{
    pageTitle = "Default Title";
}

As três formas resultam no mesmo valor sendo armazenado na variável nomeada pageTitle.

Observe que suppliedTitleé referenciado apenas uma vez ao usar o ??operador e duas vezes nos outros dois exemplos de código.

O operador também pode ser usado várias vezes na mesma expressão:

return some_Value ?? some_Value2 ?? some_Value3;

Depois que um valor não nulo é atribuído a number, ou atinge o valor final (que pode ou não ser nulo), a expressão é concluída.

Se, por exemplo, uma variável deve ser alterada para outro valor se seu valor for avaliado como nulo, desde C # 8.0, o ??=operador de atribuição de coalescência nula pode ser usado:

some_Value ??= some_Value2;

Que é uma versão mais concisa de:

some_Value = some_Value ?? some_Value2;

Em combinação com o operador nulo condicional ?. ou o operador nulo de acesso ao elemento condicional, ?[]o operador de coalescência nula pode ser usado para fornecer um valor padrão se um objeto ou membro de um objeto for nulo. Por exemplo, o seguinte retornará o título padrão se o pageobjeto for nulo ou pagenão for nulo, mas sua Titlepropriedade for:

string pageTitle = page?.Title ?? "Default Title";

CFML

A partir do ColdFusion 11, Railo 4.1, CFML oferece suporte ao operador de coalescência nulo como uma variação do operador ternário ?:,. É funcional e sintaticamente equivalente a sua contraparte C #, acima. Exemplo:

possiblyNullValue ?: valueIfNull


F #

O valor nulo não é normalmente usado em F # para valores ou variáveis. No entanto, valores nulos podem aparecer, por exemplo, quando o código F # é chamado de C #.

F # não tem um operador de coalescência nulo integrado, mas um pode ser definido conforme necessário como um operador personalizado:

let (|?) lhs rhs = (if lhs = null then rhs else lhs)

Esse operador personalizado pode então ser aplicado de acordo com o operador de coalescência nula integrado do C #:

let pageTitle = suppliedTitle |? "Default Title"

Freemarker

Valores ausentes no Apache FreeMarker normalmente causam exceções. No entanto, os valores ausentes e nulos podem ser tratados, com um valor padrão opcional:

${missingVariable!"defaultValue"}

ou, para deixar a saída em branco:

${missingVariable!}

Haskell

Os tipos em Haskell geralmente não podem ser nulos. A representação de cálculos que podem ou não retornar um resultado significativo é representada pelo tipo talvez genérico, definido na biblioteca padrão como

data Maybe a = Nothing | Just a

O operador de coalescência nulo substitui os ponteiros nulos por um valor padrão. O equivalente Haskell é uma maneira de extrair um valor de um Maybe fornecendo um valor padrão. Esta é a função de talvez.

fromMaybe     :: a -> Maybe a -> a
fromMaybe d x = case x of {Nothing -> d;Just v  -> v}

Seguem alguns exemplos de uso.

fromMaybe 0 (Just 3) -- returns 3
fromMaybe "" (Nothing) -- returns ""

JavaScript

O operador mais próximo do JavaScript é ??, o "operador de coalescência nula", que foi adicionado ao padrão na 11ª edição do ECMAScript . Em versões anteriores, ele poderia ser usado por meio de um plug-in Babel e no TypeScript . Ele avalia seu operando à esquerda e, se o valor do resultado não for "nulo" ( nullou undefined), assume esse valor como seu resultado; caso contrário, avalia o operando à direita e assume o valor resultante como seu resultado.

No exemplo a seguir, aserá atribuído o valor de bse o valor de bnão for nullou undefined, caso contrário, será atribuído 3.

const a = b ?? 3;

Antes do operador de coalescência nula, os programadores usariam o operador lógico OR ( ||). Mas onde ??procura especificamente nullou undefined, os ||olhares de operador para qualquer Falsas valor: null, undefined, "", 0, NaN, e, claro, false.

No exemplo a seguir, aserá atribuído o valor de bse o valor de bfor verdadeiro , caso contrário, será atribuído 3.

const a = b || 3;

Kotlin

Kotlin usa o ?:operador. Esta é uma escolha incomum de símbolo, dado que ?:normalmente é usado para o operador Elvis , não coalescendo nulo, mas foi inspirado em Groovy (linguagem de programação) onde nulo é considerado falso.

val title = suppliedTitle ?: "Default title"

Objective-C

Em Obj-C , o operador de coalescência nil é ?:. Ele pode ser usado para fornecer um padrão para referências nulas:

id value = valueThatMightBeNil ?: valueIfNil;

Isso é o mesmo que escrever

id value = valueThatMightBeNil ? valueThatMightBeNil : valueIfNil;

Perl

Em Perl (a partir da versão 5.10), o operador é //e o código Perl equivalente é:

$possibly_null_value // $value_if_null

O possivelmente_null_value é avaliado como nulo ou não nulo (na terminologia Perl, indefinido ou definido ). Com base na avaliação, a expressão retorna valor_se_null quando possivelmente_null_value for null, ou possivelmente_null_value caso contrário. Na ausência de efeitos colaterais, isso é semelhante ao modo como os operadores ternários ( ?:declarações) funcionam nas linguagens que os suportam. O código Perl acima é equivalente ao uso do operador ternário abaixo:

defined($possibly_null_value) ? $possibly_null_value : $value_if_null

O uso mais comum desse operador é minimizar a quantidade de código usada para uma verificação de nulo simples.

O Perl também tem um //=operador de atribuição, onde

$a //= $b

é amplamente equivalente a:

$a = $a // $b

Este operador difere dos operadores ||e mais antigos do Perl por ||=considerar definição, não verdade. Assim, eles se comportam de maneira diferente em valores que são falsos, mas definidos, como 0 ou '' (uma string de comprimento zero):

$a = 0;
$b = 1;
$c = $a // $b;  # $c = 0
$c = $a || $b;  # $c = 1

PHP

O PHP 7 introduziu um operador de coalescência nula com a ??sintaxe. Isso verifica estritamente para NULL ou uma variável / índice de matriz / propriedade inexistente. Nesse aspecto, ele atua de forma semelhante à isset()pseudo-função do PHP :

$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 (null === $user) {
    $user = $this->createGuestUser();
}
$pageTitle = $title ?? 'Default Title';

/* Equivalent to */

$pageTitle = isset($title) ? $title : 'Default Title';

A versão 7.4 do PHP adicionará o operador de atribuição de coalescência nula com a ??=sintaxe:

// 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';

Pitão

Python não tem um operador de coalescência nulo. Sua funcionalidade pode ser imitada usando uma expressão condicional:

now() if time is None else time

Houve uma proposta para adicionar operadores do tipo coalescência nula no Python 3.8, mas essa proposta foi adiada.

Funcionalidade relacionada

O oroperador do Python fornece um comportamento relacionado, mas diferente. A diferença é que ortambém retorna o termo da direita se o primeiro termo for definido, mas tem um valor que avalia Falseem um contexto booleano:

42    or "something"  # returns 42
0     or "something"  # returns "something"
False or "something"  # returns "something"
""    or "something"  # returns "something"
None  or "something"  # returns "something"

Um verdadeiro operador nulo coalescentes só voltaria "something"no último caso, e iria retornar os valores falsos-ish ( 0, False, "") nos outros exemplos.

PowerShell

Desde o PowerShell 7, o ??operador de coalescência nula fornece essa funcionalidade.

$myVar = $null
$x = $myVar ?? "something" # assigns "something"

Ferrugem

Embora não haja nenhum nullno Rust , as uniões marcadas são usadas para o mesmo propósito. Por exemplo, Result<T, E>ou Option<T>.

unwrap_or_else()serve a um propósito semelhante ao operador de coalescência nulo em outras linguagens. Se o cálculo do valor padrão não tiver efeitos colaterais, unwrap_or()pode ser usado como uma escolha mais concisa (e sem otimizações, mais eficiente).

let parsed_numbers: Vec<_> = ["1", "not a number", "3"]
    .iter()
    .map(|n| n.parse().unwrap_or_else(|_| std::i64::MIN))
    .collect();

// prints "[1, -9223372036854775808, 3]"
println!("{:?}", parsed_numbers);

SQL

No PL / SQL da Oracle , a função NVL () fornece o mesmo resultado:

NVL(possibly_null_value, 'value if null');

No SQL Server / Transact-SQL, há a função ISNULL que segue o mesmo padrão de protótipo:

ISNULL(possibly_null_value, 'value if null');

Deve-se ter atenção para não confundir ISNULL com IS NULL - este último serve para avaliar se alguns conteúdos são definidos como NULL ou não.

O padrão ANSI SQL-92 inclui a função COALESCE implementada em Oracle , SQL Server , PostgreSQL , SQLite e MySQL . A função COALESCE retorna o primeiro argumento que não é nulo. Se todos os termos forem nulos, retorna nulo.

COALESCE(possibly_null_value[, possibly_null_value, ...]);

Rápido

Em Swift , o operador de coalescência nula é ??. É usado para fornecer um padrão ao desembrulhar um tipo opcional :

optionalValue ?? valueIfNil

Por exemplo, se alguém deseja implementar algum código Swift para dar a uma página um título padrão, se nenhum estiver presente, pode-se usar a seguinte instrução:

var suppliedTitle: String? = ...
var pageTitle: String = suppliedTitle ?? "Default Title"

em vez do mais prolixo

var pageTitle: String = (suppliedTitle != nil) ? suppliedTitle! : "Default Title";

VB.NET

No VB.NET, o Ifoperador / palavra-chave atinge o efeito de operador coalescente nulo.

Dim pageTitle = If(suppliedTitle, "Default Title")

que é uma maneira mais concisa de usar sua variação

Dim pageTitle = If(suppliedTitle <> Nothing, suppliedTitle, "Default Title")

Veja também

Referências

  1. ^ BillWagner. "?? Operador (referência C #)" . msdn.microsoft.com .
  2. ^ a b "PowerShell 7 Preview 5" . PowerShell . 23/10/2019 . Página visitada em 2020-02-15 .
  3. ^ "perlop - perldoc.perl.org" . perldoc.perl.org .
  4. ^ "A linguagem de programação Swift (Swift 4): Operadores básicos" . developer.apple.com .
  5. ^ "PHP: Arquivo de notícias - 2015" . php.net .
  6. ^ "Página man do Bash" .
  7. ^ "Operador Elvis" . wikidocs.adobe.com .
  8. ^ "[RAILO-2195] adiciona suporte para o Operador Elvis - JBoss Issue Tracker" . Issues.jboss.org .
  9. ^ cartermp. "Valores nulos (F #)" . msdn.microsoft.com .
  10. ^ cartermp. "Sobrecarga do operador (F #)" . msdn.microsoft.com .
  11. ^ "Expressões" . Manual do Apache FreeMarker .
  12. ^ "Hackage" . Retirado em 10 de julho de 2015 .
  13. ^ "Especificação da linguagem ECMAScript 2020" . Ecma International . Junho de 2020.
  14. ^ "Segurança nula" ..
  15. ^ "PHP: rfc: isset_ternary" . Retirado em 16 de dezembro de 2014 .
  16. ^ Kocak, Midori. "PHP RFC: Operador de atribuição de coalescência nula" . PHP.net . Retirado em 20 de julho de 2017 .
  17. ^ https://www.python.org/dev/peps/pep-0505/
  18. ^ "Referência da linguagem SQL do banco de dados" . docs.oracle.com .
  19. ^ "COALESCE (SQL Server Compact)" . technet.microsoft.com .
  20. ^ "PostgreSQL: Documentação: 9.1: Expressões condicionais" . www.postgresql.org .
  21. ^ "Linguagem de consulta SQLite: funções centrais" . www.sqlite.org .
  22. ^ "MySQL :: MySQL 5.5 Reference Manual :: 12.3.2 Funções de comparação e operadores" . dev.mysql.com .
  23. ^ dotnet-bot. "If Operator (Visual Basic)" . docs.microsoft.com .