Comportamento do operador
Esta seção define o comportamento dos vários operadores do M.
Precedência do operador
Quando uma expressão contém vários operadores, a precedência dos operadores controla a ordem na qual os operadores individuais são avaliados. Por exemplo, a expressão x + y * z
é avaliada como x + (y * z)
porque o operador *
tem precedência maior do que o operador binário +
. A precedência de um operador é estabelecida pela definição da sua produção de gramática associada. Por exemplo, uma expressão-aditiva consiste em uma sequência de produções de expressão-multiplicativa separadas por operadores +
ou -
, permitindo assim que os operadores +
e -
tenham mais precedências do que os operadores *
e /
.
A produção expressão-entre-parênteses pode ser usada para alterar a ordenação de precedência padrão.
expressão-entre-parênteses:
(
expressão )
Por exemplo:
1 + 2 * 3 // 7
(1 + 2) * 3 // 9
A tabela a seguir resume os operadores M, listando as categorias de operador em ordem de precedência, da mais alta para a mais baixa. Os operadores em uma mesma categoria têm precedência igual.
Categoria | Expressão | Descrição |
---|---|---|
Primária | i @i |
Expressão de identificador |
(x) | Expressão entre parênteses | |
x[i] | Lookup | |
x{y} | Acesso ao item | |
x(...) | Invocação de função | |
{x, y, ...} | Inicialização de lista | |
[ i = x, ... ] | Inicialização de registro | |
... | Não implementado | |
Unário | +x | Identity |
-x | Negação | |
not x |
Negação lógica | |
Metadados | x meta y |
Associar metadados |
Multiplicativo | x * y | Multiplicação |
x / y | Divisão | |
Aditiva | x + y | Adição |
x - y | Subtração | |
Relacional | x < y | Menor que |
x > y | Maior que | |
x <= y | Inferior ou igual | |
x >= y | Maior ou igual | |
Igualitário | x = y | Igual |
x <> y | Diferente | |
Asserção de tipo | x as y |
É um tipo primitivo que permite valor nulo ou então resulta em erro |
Conformidade de tipo | x is y |
Testar se o tipo primitivo que permite valor nulo é compatível |
AND lógico | x and y |
Conjunção de curto-circuito |
OR lógico | x or y |
Disjunção de curto-circuito |
Coalesce | x ?? y |
Operador de união nula |
Operadores e metadados
Cada valor tem um valor de registro associado que pode conter informações adicionais sobre o valor. Esse registro é conhecido como o registro de metadados para um valor. Um registro de metadados pode ser associado a qualquer tipo de valor, mesmo null
. O resultado dessa associação é um novo valor com os metadados fornecidos.
Um registro de metadados é apenas um registro comum e pode conter os mesmos tipos de campos e valores que um registro regular, além de conter um registro de metadados. Associar um registro de metadados com um valor é uma ação "não intrusiva". Essa associação não altera o comportamento do valor em avaliações, exceto aqueles que inspecionam explicitamente os registros de metadados.
Cada valor tem um registro de metadados padrão, mesmo que um não tenha sido especificado. O registro de metadados padrão é vazio. Os exemplos a seguir mostram como acessar o registro de metadados de um valor de texto usando a função de biblioteca padrão Value.Metadata
:
Value.Metadata( "Mozart" ) // []
Os registros de metadados geralmente não são preservados quando um valor é usado com um operador ou função que cria um novo valor. Por exemplo, se dois valores de texto forem concatenados usando o operador &
, os metadados do valor de texto resultante serão o registro vazio []
. As seguintes expressões são equivalentes:
"Amadeus " & ("Mozart" meta [ Rating = 5 ])
"Amadeus " & "Mozart"
As funções de biblioteca padrão Value.RemoveMetadata
e Value.ReplaceMetadata
podem ser usadas para remover todos os metadados de um valor e para substituir os metadados de um valor (em vez de mesclar os metadados em metadados possivelmente existentes).
O único operador que retorna os resultados que contêm metadados é o operador meta.
Operadores recursivos estruturalmente
Os valores podem ser cíclicos. Por exemplo:
let l = {0, @l} in l
// {0, {0, {0, ... }}}
[A={B}, B={A}]
// [A = {{ ... }}, B = {{ ... }}]
O M manipula valores cíclicos mantendo o processo de construção de registros, listas e tabelas lento. Uma tentativa de criar um valor cíclico que não se beneficie de valores estruturados lentos que tenham sofrido intervenção gera um erro:
[A=B, B=A]
// [A = Error.Record("Expression.Error",
// "A cyclic reference was encountered during evaluation"),
// B = Error.Record("Expression.Error",
// "A cyclic reference was encountered during evaluation"),
// ]
Alguns operadores no M são definidos pela recursão estrutural. Por exemplo, a igualdade de listas e registros é definida pela igualdade conjunta de listas de itens e campos de registro correspondentes, respectivamente.
Para valores não cíclicos, a aplicação da recursão estrutural produz uma expansão finita do valor: valores aninhados compartilhados são percorridos repetidamente, mas o processo de recursão sempre é encerrado.
Um valor cíclico tem uma expansão infinita ao aplicar a recursão estrutural. A semântica do M não faz acomodações especiais para tais expansões infinitas. Uma tentativa de comparar valores cíclicos para igualdade, por exemplo, normalmente ficará sem recursos e terminará de maneira excepcional.
Operadores de seleção e de projeção
Os operadores de seleção e projeção permitem que os dados sejam extraídos dos valores de lista e de registro.
Acesso ao item
Um valor pode ser selecionado de uma lista ou tabela com base na respectiva posição de base zero nessa lista ou tabela usando uma expressão-de-acesso-a-item.
expressão-de-acesso-ao-item:
seleção-de-item
seleção-de-item-opcional
seleção-de-item:
primary-expression {
item-selector }
seleção-de-item-opcional:
primary-expression {
item-selector } ?
seletor-de-item:
expressão
A expressão-de-acesso-a-item x{y}
retorna:
Para obter uma lista
x
e um númeroy
, o item da listax
na posiçãoy
. O primeiro item de uma lista é considerado como tendo um índice ordinal igual a zero. Se a posição solicitada não existir na lista, um erro será gerado.Para uma tabela
x
e um númeroy
, a linha da tabelax
na posiçãoy
. A primeira linha de uma tabela é considerada como tendo um índice ordinal igual a zero. Se a posição solicitada não existir na tabela, um erro será gerado.Para uma tabela
x
e um registroy
, a linha da tabelax
que corresponde aos valores de campo do registroy
para campos com nomes de campo equivalentes aos nomes de coluna de tabela correspondentes. Se não houver nenhuma linha correspondente exclusiva na tabela, um erro será gerado.
Por exemplo:
{"a","b","c"}{0} // "a"
{1, [A=2], 3}{1} // [A=2]
{true, false}{2} // error
#table({"A","B"},{{0,1},{2,1}}){0} // [A=0,B=1]
#table({"A","B"},{{0,1},{2,1}}){[A=2]} // [A=2,B=1]
#table({"A","B"},{{0,1},{2,1}}){[B=3]} // error
#table({"A","B"},{{0,1},{2,1}}){[B=1]} // error
A expressão-de-acesso-a-item também dá suporte ao formato x{y}?
, que retorna null
quando a posição (ou correspondência) y
não existe na lista ou na tabela x
. Se houver várias correspondências para y
, um erro ainda será gerado.
Por exemplo:
{"a","b","c"}{0}? // "a"
{1, [A=2], 3}{1}? // [A=2]
{true, false}{2}? // null
#table({"A","B"},{{0,1},{2,1}}){0}? // [A=0,B=1]
#table({"A","B"},{{0,1},{2,1}}){[A=2]}? // [A=2,B=1]
#table({"A","B"},{{0,1},{2,1}}){[B=3]}? // null
#table({"A","B"},{{0,1},{2,1}}){[B=1]}? // error
O acesso ao item não força a avaliação de itens de lista ou de tabela além daquela que está sendo acessada. Por exemplo:
{ error "a", 1, error "c"}{1} // 1
{ error "a", error "b"}{1} // error "b"
Os seguintes preceitos são válidos quando o operador x{y}
de acesso ao item é avaliado:
Erros gerados durante a avaliação das expressões
x
ouy
são propagados.A expressão
x
produz uma lista ou um valor de tabela.A expressão
y
produz um valor de registro sex
produz um valor de tabela e, caso contrário, produz um valor numérico.Se
y
produzir um valor numérico e o valor dey
for negativo, um erro com o código de motivo"Expression.Error"
será gerado.Se
y
produzir um valor numérico e o valor dey
for maior ou igual à contagem dex
, um erro com o código de motivo"Expression.Error"
será gerado, a menos que o formato de operador opcionalx{y}?
seja usado; nesse caso, o valornull
será retornado.Se
x
produz um valor de tabela ey
produz um valor de registro e não há correspondências paray
emx
, um erro com o código de motivo"Expression.Error"
é gerado, a menos que o formato de operador opcionalx{y}?
seja usado; nesse caso, o valornull
é retornado.Se
x
produz um valor de tabela ey
produz um valor de registro e há várias correspondências paray
emx
, um erro com o código de motivo"Expression.Error"
é gerado.
Nenhum item em x
diferente daquele na posição y
é avaliado durante o processo de seleção de itens. (Para listas de streaming ou tabelas, os itens ou linhas que antecedem isso na posição y
são ignorados, o que pode fazer com que eles sejam avaliados, dependendo da origem da lista ou da tabela.)
Acesso ao campo
A expressão-de-acesso-ao-campo é usada para selecionar um valor de um registro ou para projetar um registro ou uma tabela para um com menos campos ou colunas, respectivamente.
expressão-de-acesso-ao-campo:
seleção-de-campo
seleção-de-campo-de-destino-implícito
projeção
projeção-de-destino-implícito
seleção-de-campo:
expressão-primária seletor-de-campo
seletor-de-campo:
seletor-de-campo-obrigatório
seletor-de-campo-opcional
seletor-de-campo-obrigatório:
[
field-name ]
seletor-de-campo-opcional:
[
field-name ] ?
nome-do-campo:
identificador-generalizado
identificador-entre-aspas
seleção-de-campo-de-destino-implícito:
seletor-de-campo
projeção:
expressão-primária projeção-obrigatória
expressão-primária projeção-opcional
projeção-obrigatória:
[
required-selector-list ]
projeção-opcional:
[
required-selector-list ] ?
lista-de-seletores-obrigatórios:
seletor-de-campo-obrigatório
required-selector-list ,
required-field-selector
projeção-de-destino-implícito:
projeção-obrigatória
projeção-opcional
A forma mais simples de acesso ao campo é a seleção de campo obrigatório. Ele usa o operador x[y]
para procurar um campo em um registro por nome de campo. Se o campo y
não existir em x
, um erro será gerado. O formato x[y]?
é usado para executar seleção de campo opcional e retorna null
se o campo solicitado não existe no registro.
Por exemplo:
[A=1,B=2][B] // 2
[A=1,B=2][C] // error
[A=1,B=2][C]? // null
O acesso coletivo de vários campos é compatível com os operadores para projeção de registro obrigatória e projeção de registro opcional. O operador x[[y1],[y2],...]
projeta o registro em um novo registro com menos campos (selecionados por y1
, y2
e ...
). Se um campo selecionado não existir, um erro será gerado. O operador x[[y1],[y2],...]
projeta o registro para um novo registro com os campos selecionados por y1
, y2
e ...
; se um campo estiver ausente, null
será usado em seu lugar.
Por exemplo:
[A=1,B=2][[B]] // [B=2]
[A=1,B=2][[C]] // error
[A=1,B=2][[B],[C]]? // [B=2,C=null]
Os formatos [y]
e [y]?
são compatíveis como uma referência abreviada ao identificador _
(sublinhado). As duas expressões a seguir são equivalentes:
[A]
_[A]
O seguinte exemplo ilustra a forma abreviada de acesso ao campo:
let _ = [A=1,B=2] in [A] //1
Os formatos [[y1],[y2],...]
e [[y1],[y2],...]?
também são compatíveis como uma abreviação e as duas expressões a seguir são, pela mesma lógica, equivalentes:
[[A],[B]]
_[[A],[B]]
O formulário abreviado é particularmente útil em combinação com a abreviação each
, uma maneira de introduzir uma função de um único parâmetro nomeado _
(para obter detalhes, confira declarações simplificadas). Juntas, as duas abreviações simplificam as expressões funcionais comuns de ordem superior:
List.Select( {[a=1, b=1], [a=2, b=4]}, each [a] = [b])
// {[a=1, b=1]}
A expressão acima é equivalente à seguinte versão mais longa, que também parece de mais difícil compreensão:
List.Select( {[a=1, b=1], [a=2, b=4]}, (_) => _[a] = _[b])
// {[a=1, b=1]}
O acesso ao campo não força a avaliação de campos além daqueles que estão sendo acessados. Por exemplo:
[A=error "a", B=1, C=error "c"][B] // 1
[A=error "a", B=error "b"][B] // error "b"
Os seguintes preceitos são válidos quando um operador x[y]
, x[y]?
, x[[y]]
ou x[[y]]?
de acesso ao campo é avaliado:
Erros gerados durante a avaliação da expressão
x
são propagados.Os erros gerados durante a avaliação do campo
y
são permanentemente associados ao campoy
e, em seguida, propagados. Qualquer acesso futuro ao campoy
vai gerar o erro idêntico.A expressão
x
produz um valor de registro ou de tabela ou resulta na geração de um erro.Se o identificador
y
nomeia um campo que não existe emx
, um erro com o código de motivo"Expression.Error"
é gerado, a menos que o formato de operador opcional...?
seja usado; nesse caso, o valornull
é retornado.
Nenhum campo de x
exceto aquele nomeado por y
é avaliado durante o processo de acesso ao campo.
Operador de metadados
O registro de metadados para um valor é alterado usando o operador meta (x meta y
).
expressão-de-metadados:
{1>unary-expression<1}
unary-expression meta
unary-expression
O exemplo a seguir constrói um valor de texto com um registro de metadados usando o operador meta
e, em seguida, acessa o registro de metadados do valor resultante usando Value.Metadata
:
Value.Metadata( "Mozart" meta [ Rating = 5 ] )
// [Rating = 5 ]
Value.Metadata( "Mozart" meta [ Rating = 5 ] )[Rating]
// 5
Os seguintes preceitos são válidos ao aplicar o operador de combinação de metadados x meta y
:
Erros gerados ao avaliar as expressões
x
ouy
são propagados.A expressão
y
precisa ser um registro, caso contrário, um erro com o código de motivo"Expression.Error"
é gerado.O registro de metadados resultante é o registro de metadados de
x
mesclado comy
. (Para obter a semântica de mesclagem de registros, confira Mesclagem de registros.)O valor resultante é o valor da expressão
x
, sem os respectivos metadados, com o registro de metadados recém-computado anexado.
As funções de biblioteca padrão Value.RemoveMetadata
e Value.ReplaceMetadata
podem ser usadas para remover todos os metadados de um valor e para substituir os metadados de um valor (em vez de mesclar os metadados em metadados possivelmente existentes). As seguintes expressões são equivalentes:
x meta y
Value.ReplaceMetadata(x, Value.Metadata(x) & y)
Value.RemoveMetadata(x) meta (Value.Metadata(x) & y)
Operadores de igualdade
O operador de igualdade =
é usado para determinar se dois valores são iguais. O operador de desigualdade <>
é usado para determinar se dois valores não são iguais.
expressão-de-igualdade:
relational-expression
relational-expression =
equality-expression
relational-expression <>
equality-expression
Por exemplo:
1 = 1 // true
1 = 2 // false
1 <> 1 // false
1 <> 2 // true
null = true // false
null = null // true
Os metadados não fazem parte da comparação de igualdade ou desigualdade. Por exemplo:
(1 meta [ a = 1 ]) = (1 meta [ a = 2 ]) // true
(1 meta [ a = 1 ]) = 1 // true
Os seguintes preceitos são válidos ao aplicar os operadores de igualdade x = y
e x <> y
:
Erros gerados ao avaliar as expressões
x
ouy
são propagados.O operador
=
terá um resultado detrue
se os valores forem iguais; caso contrário, o resultado seráfalse
.O operador
<>
terá um resultado defalse
se os valores forem iguais; caso contrário, o resultado serátrue
.Os registros de metadados não são incluídos na comparação.
Se os valores produzidos pela avaliação das expressões
x
ey
não forem do mesmo tipo de valor, os valores não serão iguais.Se os valores produzidos pela avaliação da expressão
x
ey
forem do mesmo tipo de valor, haverá regras específicas para determinar se eles são iguais, conforme definido abaixo.Os seguintes preceitos são sempre verdadeiros:
(x = y) = not (x <> y)
Os operadores de igualdade são definidos para os seguintes tipos:
- O valor
null
é igual apenas a ele mesmo.
null = null // true
null = true // false
null = false // false
- Os valores lógicos
true
efalse
são apenas iguais a eles mesmos. Por exemplo:
true = true // true
false = false // true
true = false // false
true = 1 // false
Os números são comparados usando a precisão especificada:
Se um dos dois números for
#nan
, os números não serão iguais.Quando nenhum dos números é
#nan
, eles são comparados usando uma comparação bit-a-bit do valor numérico.#nan
é o único valor que não é igual a si mesmo.Por exemplo:
1 = 1, // true
1.0 = 1 // true
2 = 1 // false
#nan = #nan // false
#nan <> #nan // true
Duas durações serão iguais se elas representarem o mesmo número de tiques de 100 nanossegundos.
Duas horas serão iguais se as magnitudes de suas partes (hora, minuto, segundo) forem iguais.
Duas datas serão iguais se as magnitudes de suas partes (ano, mês, dia) forem iguais.
Dois datetimes serão iguais se as magnitudes de suas partes (ano, mês, dia, hora, minuto, segundo) forem iguais.
Dois datetimezones serão iguais se os datetimes UTC correspondentes forem iguais. Para chegar ao datetime UTC correspondente, a diferença de horas/minutos é subtraída do componente datetime do datetimezone.
Dois valores de texto serão iguais se, ao usar uma comparação ordinal, com diferenciação de maiúsculas de minúsculas e sem diferenciação de cultura, eles tiverem o mesmo comprimento e caracteres iguais em posições correspondentes.
Dois valores de lista serão iguais se todas as condições a seguir forem verdadeiras:
As duas listas contêm o mesmo número de itens.
Os valores de cada item posicionalmente correspondente nas listas são iguais. Isso significa que não apenas as listas precisam conter itens iguais, os itens também precisam estar na mesma ordem.
Por exemplo:
{1, 2} = {1, 2} // true {2, 1} = {1, 2} // false {1, 2, 3} = {1, 2} // false
Dois registros serão iguais se todas as seguintes condições forem verdadeiras:
O número de campos é o mesmo.
Cada nome de campo de um registro também está presente no outro registro.
O valor de cada campo de um registro é igual ao campo com o mesmo nome presente no outro registro.
Por exemplo:
[ A = 1, B = 2 ] = [ A = 1, B = 2 ] // true [ B = 2, A = 1 ] = [ A = 1, B = 2 ] // true [ A = 1, B = 2, C = 3 ] = [ A = 1, B = 2 ] // false [ A = 1 ] = [ A = 1, B = 2 ] // false
Duas tabelas serão iguais se todas as condições a seguir forem verdadeiras:
O número de colunas é o mesmo.
Cada nome de coluna em uma tabela também está presente na outra tabela.
O número de linhas é o mesmo.
Cada linha tem valores iguais em células correspondentes.
Por exemplo:
#table({"A","B"},{{1,2}}) = #table({"A","B"},{{1,2}}) // true #table({"A","B"},{{1,2}}) = #table({"X","Y"},{{1,2}}) // false #table({"A","B"},{{1,2}}) = #table({"B","A"},{{2,1}}) // true
Um valor de função é igual a si mesmo, mas pode ou não ser igual a outro valor de função. Se dois valores de função forem considerados iguais, eles se comportarão de maneira idêntica quando invocados.
Dois valores de função fornecidos sempre terão a mesma relação de igualdade.
Um valor de tipo é igual a si mesmo, mas pode ou não ser igual a outro valor de tipo. Se dois valores de tipo forem considerados iguais, eles se comportarão de maneira idêntica quando consultados quanto à conformidade.
Dois valores de tipo fornecidos sempre terão a mesma relação de igualdade.
Operadores relacionais
Os operadores <
, >
, <=
e >=
são chamados de operadores relacionais.
expressão-relacional:
additive-expression
additive-expression <
relational-expression
additive-expression >
relational-expression
additive-expression <=
relational-expression
additive-expression >=
relational-expression
Esses operadores são usados para determinar a relação de ordenação relativa entre dois valores, conforme mostrado na tabela a seguir:
Operação | Resultado |
---|---|
x < y |
true se x for menor que y , caso contrário, false |
x > y |
true se x for maior que y , caso contrário, false |
x <= y |
true se x for menor ou igual a y , caso contrário, false |
x >= y |
true se x for maior ou igual a y , caso contrário, false |
Por exemplo:
0 <= 1 // true
null < 1 // null
null <= null // null
"ab" < "abc" // true
#nan >= #nan // false
#nan <= #nan // false
Os seguintes preceitos são válidos ao avaliar uma expressão que contém os operadores relacionais:
Erros gerados ao avaliar as expressões de operando
x
ouy
são propagados.Os valores produzidos pela avaliação das expressões
x
ey
devem ser um valor de binary, date, datetime, datetimezone, duration, logical, number, null, text ou time. Caso contrário, um erro com o código de motivo"Expression.Error"
é gerado.Ambos os operandos devem ser do mesmo tipo de valor ou
null
. Caso contrário, um erro com o código de motivo"Expression.Error"
é gerado.Se um ou ambos os operandos forem
null
, o resultado será o valornull
.Dois binários são comparados por byte.
Para comparar duas datas, devemos comparar suas partes de ano; se forem iguais, suas partes de mês e, se forem iguais, suas partes de dia.
Para comparar dois datetimes, devemos comparar suas partes de ano; se forem iguais, suas partes de mês; se forem iguais, suas partes de dia; se forem iguais, suas partes de hora; se forem iguais, suas partes de minuto e, se forem iguais, suas partes de segundo.
Para comparar dois datetimezones, devemos normalizá-los para UTC, subtraindo a diferença de hora/minuto e, em seguida, comparando seus componentes datetime.
Duas durações serão comparadas de acordo com o número total de tiques de 100 nanossegundos que eles representarem.
Duas lógicas são comparadas de modo que
true
é considerado maior quefalse
.Dois números
x
ey
são comparados de acordo com as regras do padrão IEEE 754:Se um dos operandos for
#nan
, o resultado seráfalse
para todos os operadores relacionais.Quando nenhum operando é
#nan
, os operadores comparam os valores dos dois operandos de ponto flutuante em relação à ordenação-∞ < -max < ... < -min < -0.0 = +0.0 < +min < ... < +max < +∞
, em que mín e máx são os menores e maiores valores finitos positivos que podem ser representados. Os nomes para -∞ e +∞ na linguagem de fórmula M são-#infinity
e#infinity
.Os efeitos notáveis dessa ordenação são:
Zeros negativos e positivos são considerados iguais.
Um valor
-#infinity
é considerado menor que todos os outros valores numéricos, mas é igual a outro-#infinity
.Um valor
#infinity
é considerado maior que todos os outros valores numéricos, mas é igual a outro#infinity
.
Dois textos são comparados usando uma comparação ordinal de caractere por caractere, que diferencia maiúsculas de minúsculas e que não diferencia a cultura.
Para comparar duas horas, devemos comparar suas partes de hora; se forem iguais, suas partes de minuto e, se forem iguais, suas partes de segundo.
Operadores lógicos condicionais
Os operadores and
e or
são chamados de operadores lógicos condicionais.
expressão-OR-lógica:
logical-and-expression
logical-and-expression or
logical-or-expression
expressão-AND-lógica:
expressão-is
is-expression and
logical-and-expression
O operador or
retorna true
quando pelo menos um de seus operandos é true
. O operando direito será avaliado se e somente se o operando esquerdo não for true
.
O operador and
retorna false
quando pelo menos um de seus operandos é false
. O operando direito será avaliado se e somente se o operando esquerdo não for false
.
As tabelas da verdade para os operadores or
e and
são mostradas abaixo, com o resultado da avaliação da expressão de operando esquerdo no eixo vertical e o resultado da avaliação da expressão do operando direito no eixo horizontal.
and |
true |
false |
null |
error |
---|---|---|---|---|
true |
true |
false |
null |
error |
false |
false |
false |
false |
false |
null |
null |
false |
null |
error |
error |
error |
error |
error |
error |
or |
true |
false |
null |
error |
---|---|---|---|---|
or |
true |
false |
null |
error |
true |
true |
true |
true |
true |
false |
true |
false |
null |
error |
null |
true |
null |
null |
error |
error |
error |
error |
error |
error |
Os seguintes preceitos são válidos ao avaliar uma expressão que contém operadores lógicos condicionais:
Erros gerados ao avaliar as expressões
x
ouy
são propagados.Os operadores lógicos condicionais são definidos sobre os tipos
logical
enull
. Se os valores de operando não forem desses tipos, um erro com o código de motivo"Expression.Error"
será gerado.O resultado é um valor lógico.
Na expressão
x
ouy
, a expressãoy
será avaliada se e somente sex
não for avaliada comotrue
.Na expressão
x
ey
, a expressãoy
será avaliada se e somente sex
não for avaliada comofalse
.
As duas últimas propriedades dão aos operadores lógicos condicionais a respectiva qualificação "condicional". Essas propriedades também são conhecidas como "curto-circuito". Essas propriedades são úteis para escrever predicados compactos protegidos. Por exemplo, as seguintes expressões são equivalentes:
d <> 0 and n/d > 1 if d <> 0 then n/d > 1 else false
Operadores aritméticos
Os operadores +
, -
, *
e /
são os operadores aritméticos.
expressão-de-adição:
multiplicative-expression
additive-expression +
multiplicative-expression
additive-expression -
multiplicative-expression
expressão-multiplicadora:
expressão-de-metadados
multiplicative-expression *
metadata-expression
multiplicative-expression /
metadata-expression
Precision
Os números em M são armazenados usando uma variedade de representações para manter o máximo possível de informações sobre números provenientes de uma variedade de fontes. Os números são convertidos apenas de uma representação para outra, conforme requerido pelos operadores aplicados a eles. Duas precisões são compatíveis com o M:
Precisão | Semântica |
---|---|
Precision.Decimal |
Representação decimal de 128 bits com um intervalo de ±1,0 x 10-28 a ±7,9 x 1.028 e 28-29 dígitos significativos. |
Precision.Double |
Representação científica usando mantissa e expoente; está em conformidade com o padrão aritmético IEEE 754 de precisão dupla binário de 64 bits IEEE 754-2008. |
As operações aritméticas são executadas escolhendo uma precisão, convertendo ambos os operandos para essa precisão (se necessário), executando a operação propriamente dita e, finalmente, retornando um número na precisão escolhida.
Os operadores aritméticos internos (+
, -
, *
e /
) usam precisão dupla. As funções de biblioteca padrão (Value.Add
, Value.Subtract
, Value.Multiply
e Value.Divide
) podem ser usadas para solicitar essas operações usando um modelo de precisão específico.
Nenhum estouro numérico é possível:
#infinity
ou-#infinity
representam valores de magnitudes grandes demais para serem representados.Nenhum fluxo negativo numérico é possível:
0
e-0
representam valores de magnitudes pequenas demais para serem representados.O valor especial do IEEE 754
#nan
(NaN – não é um número) é usado para cobrir casos que não são matematicamente válidos, como uma divisão de zero por zero.A conversão de precisão decimal para dupla é executada por meio do arredondamento de números decimais para o valor duplo equivalente mais próximo.
A conversão da precisão de dupla para decimal é executada por meio do arredondamento de números duplos para o valor decimal equivalente mais próximo e, se necessário, estourando para valores
#infinity
ou-#infinity
.
Operador de adição
A interpretação do operador de adição (x + y
) depende do tipo de valor das expressões x e y avaliadas, da seguinte maneira:
x | a | Resultado | Interpretação |
---|---|---|---|
type number |
type number |
type number |
Soma numérica |
type number |
null |
null |
|
null |
type number |
null |
|
type duration |
type duration |
type duration |
Soma numérica de magnitudes |
type duration |
null |
null |
|
null |
type duration |
null |
|
type datetime |
type duration |
type datetime |
Deslocamento de data/hora por duração |
type duration |
type datetime |
type datetime |
|
type datetime |
null |
null |
|
null |
type datetime |
null |
Na tabela, type
datetime representa qualquer um entre type date
, type datetime
, type datetimezone
ou type time
. Ao adicionar uma duração e um valor de algum tipo de datetime, o valor resultante é desse mesmo tipo.
Para outras combinações de valores além daquelas listadas na tabela, um erro com o código de motivo "Expression.Error"
é gerado. Cada uma das combinações é abordada nas seções a seguir.
Os erros gerados ao avaliar qualquer um dos dois operandos são propagados.
Soma numérica
A soma de dois números é computada usando o operador de adição, produzindo um número.
Por exemplo:
1 + 1 // 2
#nan + #infinity // #nan
O operador de adição +
usado em números usa precisão dupla. A função de biblioteca padrão Value.Add
pode ser usada para especificar a precisão decimal. Os seguintes preceitos são válidos ao computar uma soma de números:
A soma em precisão dupla é computada de acordo com as regras de aritmética de IEEE 754 de precisão dupla binária de 64 bits, IEEE 754-2008. A tabela a seguir lista os resultados de todas as combinações possíveis de valores finitos diferentes de zero, zeros, infinitos e NaNs. Na tabela,
x
ey
são valores finitos diferentes de zero ez
é o resultado dex + y
. Sex
ey
tiverem a mesma magnitude, mas sinais opostos,z
será zero positivo. Sex + y
for grande demais para ser representado no tipo de destino,z
será um infinito com o mesmo sinal quex + y
.+ a +0 -0 +∞ -∞ NaN x z x x +∞ -∞ NaN +0 a +0 +0 +∞ -∞ NaN -0 a +0 -0 +∞ -∞ NaN +∞ +∞ +∞ +∞ +∞ NaN NaN -∞ -∞ -∞ -∞ NaN -∞ NaN NaN NaN NaN NaN NaN NaN NaN A soma em precisão decimal é computada sem perda de precisão. A escala do resultado é maior que as escalas dos dois operandos.
Soma das durações
A soma de duas durações é a duração que representa a soma do número de tiques de 100 nanossegundos representada pelas durações. Por exemplo:
#duration(2,1,0,15.1) + #duration(0,1,30,45.3)
// #duration(2, 2, 31, 0.4)
Deslocamento de data/hora por duração
Um datetime x
e uma duração y
podem ser adicionados usando x + y
para computar um novo datetime cuja distância de x
em uma linha do tempo linear é exatamente a magnitude de y
. Aqui, datetime representa qualquer uma das opções Date
, DateTime
, DateTimeZone
e Time
; assim, um resultado não nulo será do mesmo tipo. A diferença de datetime por duração pode ser calculado da seguinte maneira:
Se o valor de dias desde o início da época de datetime for especificado, crie um datetime com os seguintes elementos de informação:
Calcule um novo equivalente de dias desde o início da época, a fim de dividir a magnitude de y pelo número de tiques de 100 nanossegundos em um período de 24 horas, truncando a parte decimal do resultado e adicionando esse valor aos dias desde o início da época de x.
Calcule uma nova contagem de tiques desde a meia-noite equivalente à adição da magnitude de y aos tiques desde a meia-noite de x, módulo o número de tiques de 100 nanossegundos em um período de 24 horas. Se x não especificar um valor para tiques desde a meia-noite, um valor de 0 será assumido.
Copie o valor da diferença em minutos em relação ao UTC, inalterado, de x.
Se o valor de dias desde o início da época de datetime não for especificado, crie um datetime com os seguintes elementos de informação especificados:
Calcule uma nova contagem de tiques desde a meia-noite equivalente à adição da magnitude de y aos tiques desde a meia-noite de x, módulo o número de tiques de 100 nanossegundos em um período de 24 horas. Se x não especificar um valor para tiques desde a meia-noite, um valor de 0 será assumido.
Copie os valores de dias desde o início da época e a diferença em minutos em relação ao UTC, inalterados, de x.
Os exemplos a seguir mostram o cálculo da soma temporal absoluta quando o datetime especifica os dias desde o início da época:
#date(2010,05,20) + #duration(0,8,0,0)
//#datetime( 2010, 5, 20, 8, 0, 0 )
//2010-05-20T08:00:00
#date(2010,01,31) + #duration(30,08,0,0)
//#datetime(2010, 3, 2, 8, 0, 0)
//2010-03-02T08:00:00
#datetime(2010,05,20,12,00,00,-08) + #duration(0,04,30,00)
//#datetime(2010, 5, 20, 16, 30, 0, -8, 0)
//2010-05-20T16:30:00-08:00
#datetime(2010,10,10,0,0,0,0) + #duration(1,0,0,0)
//#datetime(2010, 10, 11, 0, 0, 0, 0, 0)
//2010-10-11T00:00:00+00:00
O exemplo a seguir mostra o cálculo da diferença de datetime por duração para uma determinada hora:
#time(8,0,0) + #duration(30,5,0,0)
//#time(13, 0, 0)
//13:00:00
Operador de subtração
A interpretação do operador de subtração (x - y
) depende do tipo de valor das expressões x
e y
avaliadas, da seguinte maneira:
x | Y | Resultado | Interpretação |
---|---|---|---|
type number |
type number |
type number |
Diferença numérica |
type number |
null |
null |
|
null |
type number |
null |
|
type duration |
type duration |
type duration |
Diferença numérica de magnitudes |
type duration |
null |
null |
|
null |
type duration |
null |
|
type datetime |
type datetime |
type duration |
Duração entre datetimes |
type datetime |
type duration |
type datetime |
Deslocamento de Datetime por duração negada |
type datetime |
null |
null |
|
null |
type datetime |
null |
Na tabela, type
datetime representa qualquer um entre type date
, type datetime
, type datetimezone
ou type time
. Ao subtrair uma duração de um valor de algum tipo de datetime, o valor resultante é desse mesmo tipo.
Para outras combinações de valores além daquelas listadas na tabela, um erro com o código de motivo "Expression.Error"
é gerado. Cada uma das combinações é abordada nas seções a seguir.
Os erros gerados ao avaliar qualquer um dos dois operandos são propagados.
Diferença numérica
A diferença entre dois números é computada usando o operador de subtração, produzindo um número. Por exemplo:
1 - 1 // 0
#nan - #infinity // #nan
O operador de subtração -
usado em números usa precisão dupla. A função de biblioteca padrão Value.Subtract
pode ser usada para especificar a precisão decimal. Os seguintes preceitos são válidos ao computar uma diferença de números:
A diferença em precisão dupla é computada de acordo com as regras de aritmética de IEEE 754 de precisão dupla binária de 64 bits, IEEE 754-2008. A tabela a seguir lista os resultados de todas as combinações possíveis de valores finitos diferentes de zero, zeros, infinitos e NaNs. Na tabela,
x
ey
são valores finitos diferentes de zero ez
é o resultado dex - y
. Sex
ey
forem iguais,z
será zero positivo. Sex - y
for grande demais para ser representado no tipo de destino,z
será um infinito com o mesmo sinal quex - y
.- a +0 -0 +∞ -∞ NaN x z x x -∞ +∞ NaN +0 -y +0 +0 -∞ +∞ NaN -0 -y -0 +0 -∞ +∞ NaN +∞ +∞ +∞ +∞ NaN +∞ NaN -∞ -∞ -∞ -∞ -∞ NaN NaN NaN NaN NaN NaN NaN NaN NaN A diferença em precisão decimal é computada sem perda de precisão. A escala do resultado é maior que as escalas dos dois operandos.
Diferença de durações
A diferença entre duas durações é a duração que representa a diferença entre o número de tiques de 100 nanossegundos representada pelas durações. Por exemplo:
#duration(1,2,30,0) - #duration(0,0,0,30.45)
// #duration(1, 2, 29, 29.55)
Deslocamento de Datetime por duração negada
Um datetime x
e uma duração y
podem ser subtraídos usando x - y
para computar um novo datetime. Aqui, datetime representa qualquer um entre date
, datetime
, datetimezone
ou time
. O datetime resultante tem uma distância de x
em uma linha do tempo linear, que é exatamente a magnitude de y
, na direção oposta ao sinal de y
. A subtração de durações positivas gera resultados que são regressivos no tempo em relação a x
, enquanto a subtração de valores negativos gera resultados que são progressivos no tempo.
#date(2010,05,20) - #duration(00,08,00,00)
//#datetime(2010, 5, 19, 16, 0, 0)
//2010-05-19T16:00:00
#date(2010,01,31) - #duration( 30,08,00,00)
//#datetime(2009, 12, 31, 16, 0, 0)
//2009-12-31T16:00:00
Duração entre dois datetimes
Dois datetimes t
e u
podem ser subtraídos usando t - u
para computar a duração entre eles. Aqui, datetime representa qualquer um entre date
, datetime
, datetimezone
ou time
. A duração produzida subtraindo u
de t
precisa resultar t
quando adicionada a u
.
#date(2010,01,31) - #date(2010,01,15)
// #duration(16,00,00,00)
// 16.00:00:00
#date(2010,01,15)- #date(2010,01,31)
// #duration(-16,00,00,00)
// -16.00:00:00
#datetime(2010,05,20,16,06,00,-08,00) -
#datetime(2008,12,15,04,19,19,03,00)
// #duration(521,22,46,41)
// 521.22:46:41
A subtração t - u
quando u > t
resulta em uma duração negativa:
#time(01,30,00) - #time(08,00,00)
// #duration(0, -6, -30, 0)
Os seguintes preceitos são válidos ao subtrair dois datetimes usando t - u
:
- u + (t - u) = t
Operador de multiplicação
A interpretação do operador de multiplicação (x * y
) depende do tipo de valor das expressões x e y avaliadas, da seguinte maneira:
X | Y | Resultado | Interpretação |
---|---|---|---|
type number |
type number |
type number |
Produto numérico |
type number |
null |
null |
|
null |
type number |
null |
|
type duration |
type number |
type duration |
Múltiplo da duração |
type number |
type duration |
type duration |
Múltiplo da duração |
type duration |
null |
null |
|
null |
type duration |
null |
Para outras combinações de valores além daquelas listadas na tabela, um erro com o código de motivo "Expression.Error"
é gerado. Cada uma das combinações é abordada nas seções a seguir.
Os erros gerados ao avaliar qualquer um dos dois operandos são propagados.
Produto numérico
O produto de dois números é computado usando o operador de multiplicação, produzindo um número. Por exemplo:
2 * 4 // 8
6 * null // null
#nan * #infinity // #nan
O operador de multiplicação *
usado em números usa precisão dupla. A função de biblioteca padrão Value.Multiply
pode ser usada para especificar a precisão decimal. Os seguintes preceitos são válidos ao computar um produto de números:
O produto em precisão dupla é computado de acordo com as regras de aritmética de IEEE 754 de precisão dupla binária de 64 bits, IEEE 754-2008. A tabela a seguir lista os resultados de todas as combinações possíveis de valores finitos diferentes de zero, zeros, infinitos e NaNs. Na tabela,
x
ey
são valores positivos finitos.z
é o resultado dex * y
. Se o resultado é grande demais para o tipo de destino,z
é infinito. Se o resultado é pequeno demais para o tipo de destino,z
é zero.* +y -y +0 -0 +∞ -∞ NaN +x +z -Z +0 -0 +∞ -∞ NaN -x -Z +z -0 +0 -∞ +∞ NaN +0 +0 -0 +0 -0 NaN NaN NaN -0 -0 +0 -0 +0 NaN NaN NaN +∞ +∞ -∞ NaN NaN +∞ -∞ NaN -∞ -∞ +∞ NaN NaN -∞ +∞ NaN NaN NaN NaN NaN NaN NaN NaN NaN O produto em precisão decimal é computado sem perda de precisão. A escala do resultado é maior que as escalas dos dois operandos.
Múltiplos de durações
O produto de uma duração e um número é a duração que representa o número de tiques de 100 nanossegundos representado pela multiplicação do operando de duração pelo operando de número. Por exemplo:
#duration(2,1,0,15.1) * 2
// #duration(4, 2, 0, 30.2)
Operador de divisão
A interpretação do operador de divisão (x / y
) depende do tipo de valor das expressões x
e y
avaliadas, da seguinte maneira:
X | Y | Resultado | Interpretação |
---|---|---|---|
type number |
type number |
type number |
Quociente numérico |
type number |
null |
null |
|
null |
type number |
null |
|
type duration |
type number |
type duration |
Fração de uma duração |
type duration |
type duration |
type number |
Quociente numérico de durações |
type duration |
null |
null |
|
null |
type duration |
null |
Para outras combinações de valores além daquelas listadas na tabela, um erro com o código de motivo "Expression.Error"
é gerado. Cada uma das combinações é abordada nas seções a seguir.
Os erros gerados ao avaliar qualquer um dos dois operandos são propagados.
Quociente numérico
O quociente de dois números é computado usando o operador de divisão, produzindo um número. Por exemplo:
8 / 2 // 4
8 / 0 // #infinity
0 / 0 // #nan
0 / null // null
#nan / #infinity // #nan
O operador de divisão /
usado em números usa precisão dupla. A função de biblioteca padrão Value.Divide
pode ser usada para especificar a precisão decimal. Os seguintes preceitos são válidos ao calcular um quociente de números:
O quociente em precisão dupla é computado de acordo com as regras de aritmética de IEEE 754 de precisão dupla binária de 64 bits, IEEE 754-2008. A tabela a seguir lista os resultados de todas as combinações possíveis de valores finitos diferentes de zero, zeros, infinitos e NaNs. Na tabela,
x
ey
são valores positivos finitos.z
é o resultado dex / y
. Se o resultado é grande demais para o tipo de destino,z
é infinito. Se o resultado é pequeno demais para o tipo de destino,z
é zero./ +y -y +0 -0 +∞ -∞ NaN +x +z -Z +∞ -∞ +0 -0 NaN -x -Z +z -∞ +∞ -0 +0 NaN +0 +0 -0 NaN NaN +0 -0 NaN -0 -0 +0 NaN NaN -0 +0 NaN +∞ +∞ -∞ +∞ -∞ NaN NaN NaN -∞ -∞ +∞ -∞ +∞ NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN A soma em precisão decimal é computada sem perda de precisão. A escala do resultado é maior que as escalas dos dois operandos.
Quociente de durações
O quociente de duas durações é o número que representa o quociente do número de tiques de 100 nanossegundos representada pelas durações. Por exemplo:
#duration(2,0,0,0) / #duration(0,1,30,0)
// 32
Durações dimensionadas
O quociente de uma duração x
e um número y
é a duração que representa o quociente do número de tiques de 100 nanossegundos representados pela duração x
e o número y
. Por exemplo:
#duration(2,0,0,0) / 32
// #duration(0,1,30,0)
Combinação de estrutura
O operador de combinação (x & y
) é definido para os seguintes tipos de valores:
X | Y | Resultado | Interpretação |
---|---|---|---|
type text |
type text |
type text |
Concatenação |
type text |
null |
null |
|
null |
type text |
null |
|
type date |
type time |
type datetime |
Mesclar |
type date |
null |
null |
|
null |
type time |
null |
|
type list |
type list |
type list |
Concatenação |
type record |
type record |
type record |
Mesclar |
type table |
type table |
type table |
Concatenação |
Concatenação
Dois textos, duas listas ou dois valores de tabela podem ser concatenados usando x & y
.
Este exemplo ilustra a concatenação de valores de texto:
"AB" & "CDE" // "ABCDE"
Este exemplo ilustra a concatenação de listas:
{1, 2} & {3} // {1, 2, 3}
Os seguintes preceitos são válidos ao concatenar dois valores usando x & y
:
Erros gerados ao avaliar as expressões
x
ouy
são propagados.Nenhum erro será propagado se um item de
x
ou dey
contiver um erro.O resultado da concatenação de dois valores de texto é um valor de texto que contém o valor de x seguido imediatamente por y. Se um dos operandos for nulo e o outro for um valor de texto, o resultado será nulo.
O resultado da concatenação de duas listas é uma lista que contém todos os itens de
x
seguidos por todos os itens dey
.O resultado da concatenação de duas tabelas é uma tabela contendo a união das colunas das tabelas dos dois operandos. A ordenação de colunas de
x
é preservada, seguida pelas colunas que aparecem apenas emy
, preservando a ordenação relativa delas. Para colunas que aparecem apenas em um dos operandos,null
é usado para preencher valores de célula para o outro operando.
Mesclar
Mesclagem de registros
Dois registros podem ser mesclados usando x & y
, produzindo um registro que inclui campos de x
e y
.
Os exemplos a seguir ilustram a mesclagem de registros:
[ x = 1 ] & [ y = 2 ] // [ x = 1, y = 2 ]
[ x = 1, y = 2 ] & [ x = 3, z = 4 ] // [ x = 3, y = 2, z = 4 ]
Os seguintes preceitos são válidos ao mesclar dois registros usando x + y
:
Erros gerados ao avaliar as expressões
x
ouy
são propagados.Se um campo aparecer tanto em
x
quanto emy
, o valor dey
será usado.A ordem dos campos no registro resultante é a de
x
, seguida pelos campos emy
que não fazem parte dex
, na mesma ordem em que aparecem emy
.A mesclagem de registros não causa a avaliação dos valores.
Nenhum erro é gerado devido a um campo conter um erro.
O resultado é um registro.
Mesclagem de data e hora
Uma data x
pode ser mesclada com uma hora y
usando x & y
, produzindo um datetime que combina as partes de x
e y
.
O exemplo a seguir ilustra a mesclagem de uma data e uma hora:
#date(2013,02,26) & #time(09,17,00)
// #datetime(2013,02,26,09,17,00)
Os seguintes preceitos são válidos ao mesclar dois registros usando x + y
:
Erros gerados ao avaliar as expressões
x
ouy
são propagados.O resultado é um datetime.
Operadores unários
Os operadores +
, -
e not
são operadores unários.
expressão-unária:
expressão-de-tipo
+
expressão unária
-
expressão unária
not
expressão unária
Operador de adição de unário
O operador de adição de unário (+x
) é definido para os seguintes tipos de valores:
X | Resultado | Interpretação |
---|---|---|
type number |
type number |
Adição de unário |
type duration |
type duration |
Adição de unário |
null |
nulo |
Para outros valores, um erro com o código de motivo "Expression.Error"
é gerado.
O operador de adição de unário permite que um sinal de +
seja aplicado a um valor numérico, datetime ou nulo. O resultado é esse mesmo valor. Por exemplo:
+ - 1 // -1
+ + 1 // 1
+ #nan // #nan
+ #duration(0,1,30,0) // #duration(0,1,30,0)
Os seguintes preceitos são válidos ao avaliar o operador de adição de unário +x
:
Os erros gerados ao avaliar
x
são propagados.Se o resultado da avaliação de
x
não for um valor numérico, um erro com o código de motivo"Expression.Error"
será gerado.
Operador de subtração de unário
O operador de subtração de unário (-x
) é definido para os seguintes tipos de valores:
X | Resultado | Interpretação |
---|---|---|
type number |
type number |
Negação |
type duration |
type duration |
Negação |
null |
null |
Para outros valores, um erro com o código de motivo "Expression.Error"
é gerado.
O operador de subtração de unário é usado para alterar o sinal de um número ou duração. Por exemplo:
- (1 + 1) // -2
- - 1 // 1
- - - 1 // -1
- #nan // #nan
- #infinity // -#infinity
- #duration(1,0,0,0) // #duration(-1,0,0,0)
- #duration(0,1,30,0) // #duration(0,-1,-30,0)
Os seguintes preceitos são válidos ao avaliar o operador de subtração unário -x
:
Os erros gerados ao avaliar
x
são propagados.Se a expressão for um número, o resultado será o valor numérico da expressão
x
com seu sinal alterado. Se o valor for um NaN, o resultado também será um NaN.
Operador de negação lógica
O operador de negação lógica (not
) é definido para os seguintes tipos de valores:
X | Resultado | Interpretação |
---|---|---|
type logical |
type logical |
Negação |
null |
null |
Esse operador computa a operação not
lógica em um determinado valor lógico. Por exemplo:
not true // false
not false // true
not (true and true) // false
Os seguintes preceitos são válidos ao avaliar o operador lógico de negação not x
:
Os erros gerados ao avaliar
x
são propagados.O valor produzido da avaliação da expressão x precisa ser um valor lógico, caso contrário, um erro com o código de motivo
"Expression.Error"
precisará ser gerado. Se o valor fortrue
, o resultado seráfalse
. Se o operando forfalse
, o resultado serátrue
.
O resultado é um valor lógico.
Operadores de tipo
Os operadores is
e as
são conhecidos como operadores de tipo.
Operador de compatibilidade de tipo
O operador de compatibilidade de tipo x is y
é definido para os seguintes tipos de valores:
X | Y | Resultado |
---|---|---|
type any |
tipo-primitivo-que-permite-valor-nulo | type logical |
A expressão x is y
retornará true
se o tipo atribuído de x
for compatível com y
e retornará false
se o tipo atribuído de x
for incompatível com y
. y
precisa ser um tipo-primitivo-que-permite-valor-nulo.
expressão-is:
expressão-as
is-expression is
nullable-primitive-type
tipo-primitivo-que-permite-valor-nulo:
nullable
opcional tipo-primitivo
A compatibilidade de tipo, conforme compatível com o operador is
, é um subconjunto de compatibilidade de tipo geral e é definida usando as seguintes regras:
Se
x
for nulo, ele será compatível sey
for do tipoany
, do tiponull
ou de um tipo anulável.Se
x
for não nulo, ele será compatível se o tipo primitivo dex
for o mesmo quey
.
Os seguintes preceitos são válidos ao avaliar a expressão x is y
:
- Um erro gerado ao avaliar a expressão
x
é propagado.
Operador de asserção de tipo
O operador de asserção de tipo x as y
é definido para os seguintes tipos de valores:
X | Y | Resultado |
---|---|---|
type any |
tipo-primitivo-que-permite-valor-nulo | type any |
A expressão x as y
declara que o valor x
é compatível com y
, conforme o operador is
. Se não for compatível, um erro será gerado. y
precisa ser um tipo-primitivo-que-permite-valor-nulo.
expressão-as:
expressão de igualdade
as-expression as
nullable-primitive-type
A expressão x as y
é avaliada desta maneira:
Uma verificação de compatibilidade de tipo
x is y
é executada e a asserção retornax
inalterado se o teste é executado com sucesso.Se a verificação de compatibilidade falhar, um erro com o código de motivo
"Expression.Error"
será gerado.
Exemplos:
1 as number // 1
"A" as number // error
null as nullable number // null
Os seguintes preceitos são válidos ao avaliar a expressão x as y
:
- Um erro gerado ao avaliar a expressão
x
é propagado.
Operador de união
O operador de união ??
retornará o resultado do operando esquerdo dele caso ele não seja nulo; do contrário, ele retornará o resultado do operando direito. O operando direito será avaliado se e somente se o operando esquerdo for nulo.