Comportamento degli operatori

Questa sezione definisce il comportamento dei diversi operatori M.

Precedenza tra gli operatori

Se un'espressione contiene più operatori, la precedenza degli operatori determina l'ordine in cui vengono valutati i singoli operatori. Ad esempio, l'espressione x + y * z viene valutata come x + (y * z) perché l'operatore * ha la precedenza rispetto all'operatore + binario. La precedenza di un operatore viene stabilita dalla definizione della produzione grammaticale associata. Un'additive-expression, ad esempio, è costituita da una sequenza di multiplicative-expression separate dagli operatori + o -, assegnando in questo modo una precedenza inferiore agli operatori + e - rispetto agli operatori * e /.

La produzione di parenthesized-expression può essere usata per modificare l'ordine di precedenza predefinito.

parenthesized-expression:
      ( expression )

Ad esempio:

1 + 2 * 3       // 7 
(1 + 2) * 3     // 9

La tabella seguente riepiloga gli operatori M, elencando le categorie di operatori in ordine di precedenza, dalla più alta alla più bassa. Gli operatori della stessa categoria hanno uguale precedenza.

Categoria Expression Descrizione
Primari i
@i
Espressione identificatore
(x) Espressione racchiusa tra parentesi
x[i] Cerca
x{y} Accesso agli elementi
x(...) Chiamata di funzione
{x, y, ...} Inizializzazione elenco
[ i = x, ... ] Inizializzazione del record
... Non implementato
Unario +x Identità
-x Negazione
not x Negazione logica
Metadati UFX x meta y Associare i metadati
Moltiplicazione x * y Moltiplicazione
x / y Divisione
Additive x + y Addizione
x - y Sottrazione
Relazionale x < y Minore di
x > y Maggiore di
x <= y Minore di o uguale a
x >= y Maggiore di o uguale a
Equality x = y Uguale
x <> y Not equal
Asserzione di tipo x as y Errore o tipo primitivo nullable compatibile
Conformità del tipo x is y Testa se è un tipo primitivo nullable compatibile
AND logico x and y Congiunzione di corto circuito
OR logico x or y Disgiunzione di cortocircuito
Coalesce x ?? y Operatore di coalescenza di valori Null

Operatori e metadati

A ogni valore è associato un valore di record che può includere informazioni aggiuntive sul valore. Questo record è detto record di metadati per un valore. Un record di metadati può essere associato a qualsiasi tipo di valore, anche null. Il risultato di tale associazione è un nuovo valore con i metadati specificati.

Un record di metadati è un normale record e può contenere qualsiasi campo e valore possa essere contenuto in un normale record e contenga a sua volta un record di metadati. L'associazione di un record di metadati a un valore è "non invasiva". Non comporta la modifica del comportamento del valore nelle valutazioni, a eccezione di quelle che ispezionano in modo esplicito i record di metadati.

Ogni valore ha un record di metadati predefinito, anche se non ne è stato specificato uno. Il record di metadati predefinito è vuoto. Gli esempi seguenti illustrano l'accesso al record di metadati di un valore di testo tramite la funzione della libreria standard Value.Metadata:

Value.Metadata( "Mozart" )   // []

I record di metadati in genere non vengono conservati quando un valore viene usato con un operatore o una funzione che costruisce un nuovo valore. Ad esempio, se due valori di testo vengono concatenati tramite l'operatore &, i metadati del valore di testo risultante sono un record vuoto []. Le espressioni seguenti sono equivalenti:

"Amadeus " & ("Mozart" meta [ Rating = 5 ])  
"Amadeus " & "Mozart"

È possibile usare le funzioni della libreria standard Value.RemoveMetadata e Value.ReplaceMetadata per rimuovere tutti i metadati da un valore e sostituire i metadati di un valore (invece di unire i metadati nei metadati eventualmente esistenti).

Il solo operatore che restituisce risultati contenenti metadati è l'operatore meta.

Operatori ricorsivi a livello strutturale

I valori possono essere ciclici, Ad esempio:

let l = {0, @l} in l
// {0, {0, {0, ... }}}
[A={B}, B={A}]
// [A = {{ ... }}, B = {{ ... }}]

M gestisce i valori ciclici mantenendo la costruzione di record, elenchi e tabelle lazy. Un tentativo di costruire un valore ciclico che non trae vantaggio dai valori strutturati lazy inseriti genera un errore:

[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"), 
// ]

Alcuni operatori in M sono definiti dalla ricorsione strutturale. Ad esempio, l'uguaglianza di record ed elenchi è definita dall'uguaglianza congiunta dei campi di record e degli elenchi di elementi corrispondenti, rispettivamente.

Per i valori non ciclici, l'applicazione di una ricorsione strutturale genera un'espansione finita del valore: i valori annidati condivisi verranno attraversati ripetutamente, ma il processo di ricorsione termina sempre.

Un valore ciclico ha un'espansione infinita quando si applica una ricorsione strutturale. La semantica di M non prevede la presenza di tali espansioni infinite. Un tentativo di confrontare valori ciclici per verificarne l'uguaglianza, ad esempio, in genere esaurirà le risorse e verrà terminato con un'eccezione.

Operatori di selezione e proiezione

Gli operatori di selezione e proiezione consentono di estrarre i dati dai valori di elenco e di record.

Accesso agli elementi

Un valore può essere selezionato da un elenco o da una tabella a seconda della posizione in base zero all'interno di tale elenco o tabella usando un'espressione item-access-expression.

item-access-expression:
      item-selection
      optional-item-selection
item-selection:
      primary-expression
{ item-selector }
optional-item-selection:
      primary-expression
{ item-selector } ?
item-selector:
      expression

L'espressione item-access-expression x{y} restituisce:

  • Per un elenco x e un numero y, l'elemento dell'elenco x nella posizione y. Si presuppone che il primo elemento di un elenco abbia un indice ordinale pari a zero. Se la posizione richiesta non esiste nell'elenco, viene generato un errore.

  • Per una tabella x e un numero y, la riga della tabella x nella posizione y. Si presuppone che la prima riga di una tabella abbia un indice ordinale pari a zero. Se la posizione richiesta non esiste nella tabella, viene generato un errore.

  • Per una tabella x e un record y, la riga della tabella x che corrisponde ai valori di campo del record y per i campi con nomi di campo che corrispondono ai relativi nomi delle colonne della tabella. Se nella tabella non è presente alcuna riga univoca corrispondente, viene generato un errore.

Ad esempio:

{"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

item-access-expression supporta anche la forma x{y}?, che restituisce null quando la posizione (o la corrispondenza) y non esiste nell'elenco o nella tabella x. Se sono presenti più corrispondenze per y, viene comunque generato un errore.

Ad esempio:

{"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

L'accesso agli elementi non forza la valutazione di elementi dell'elenco o della tabella diversi da quello a cui si accede, Ad esempio:

{ error "a", 1, error "c"}{1}  // 1 
{ error "a", error "b"}{1}     // error "b"

Quando viene valutato l'operatore di accesso all'elemento x{y}, tenere presente quanto segue:

  • Gli errori generati durante la valutazione delle espressioni x o y vengono propagati.

  • L'espressione x produce un elenco o un valore di tabella.

  • L'espressione y produce un valore numerico o, se x produce un valore di tabella, un valore di record.

  • Se y produce un valore numerico e il valore di y è negativo, viene generato un errore con il codice motivo "Expression.Error".

  • Se y produce un valore numerico e il valore di y è maggiore o uguale al conteggio di x, viene generato un errore con il codice motivo "Expression.Error" a meno che non venga usata la forma dell'operatore facoltativo x{y}?, nel qual caso viene restituito il valore null.

  • Se x produce un valore di tabella e y produce un valore di record e non sono presenti corrispondenze per y in x, viene generato un errore con il codice motivo "Expression.Error" a meno che non venga usata la forma dell'operatore facoltativo x{y}?, nel qual caso viene restituito il valore null.

  • Se x produce un valore di tabella e y produce un valore di record e sono presenti più corrispondenze per y in x, viene generato un errore con il codice motivo "Expression.Error".

Nessun elemento in x diverso da quello nella posizione y viene valutato durante il processo di selezione dell'elemento. Per gli elenchi o le tabelle di flusso, gli elementi o le righe che lo precedono nella posizione y vengono ignorati e possono quindi venire valutati, a seconda dell'origine dell'elenco o della tabella.

Accesso ai campi

field-access-expression viene usata per selezionare un valore da un record o per proiettare un record o una tabella in una con meno campi o colonne, rispettivamente.

field-access-expression:
      field-selection
      implicit-target-field-selection
      proiezione
      implicit-target-projection
field-selection:
      primary-expression field-selector
field-selector:
      required-field-selector
      optional-field-selector
required-field-selector:

      [ field-name ]
optional-field-selector:
      [ field-name ] ?
field-name:
      generalized-identifier
      quoted-identifier
implicit-target-field-selection:
      field-selector
projection:
      primary-expression required-projection
      primary-expression optional-projection
required-projection:

      [ required-selector-list ]
optional-projection:
      [ required-selector-list ] ?
required-selector-list:
      required-field-selector
      required-selector-list
, required-field-selector
implicit-target-projection:
      required-projection
      optional-projection

La forma più semplice di accesso a un campo è la selezione del campo obbligatoria, che usa l'operatore x[y] per cercare un campo in un record in base al nome del campo. Se il campo y non esiste in x, viene generato un errore. La forma x[y]? viene usata per eseguire la selezione del campo facoltativa e restituisce null se il campo richiesto non esiste nel record.

Ad esempio:

[A=1,B=2][B]       // 2 
[A=1,B=2][C]       // error 
[A=1,B=2][C]?      // null

L'accesso collettivo di più campi è supportato dagli operatori per la proiezione del record obbligatoria e la proiezione del record facoltativa. L'operatore x[[y1],[y2],...] proietta il record in un nuovo record con meno campi (selezionati da y1, y2, ...). Se un campo selezionato non esiste, viene generato un errore. L'operatore x[[y1],[y2],...] proietta il record in un nuovo record con i campi selezionati da y1, y2, .... Se un campo non è presente, viene usato null, Ad esempio:

[A=1,B=2][[B]]           // [B=2] 
[A=1,B=2][[C]]           // error 
[A=1,B=2][[B],[C]]?      // [B=2,C=null]

Le forme [y] e [y]? sono supportate come riferimento di sintassi abbreviata all'identificatore _ (carattere di sottolineatura). Le due espressioni seguenti sono equivalenti:

[A]                 
_[A]

L'esempio seguente illustra la forma abbreviata di accesso ai campi:

let _ = [A=1,B=2] in [A] //1

Anche le forme [[y1],[y2],...] e [[y1],[y2],...]? sono supportate come sintassi abbreviata e anche le due espressioni seguenti sono equivalenti:

[[A],[B]]                 
_[[A],[B]]

La forma abbreviata è particolarmente utile in combinazione con la sintassi abbreviata each, che consente di introdurre una funzione di un singolo parametro denominato _. Per informazioni dettagliate, vedere Dichiarazioni semplificate. Insieme, le due sintassi abbreviate semplificano le espressioni funzionali comuni di ordine superiore:

List.Select( {[a=1, b=1], [a=2, b=4]}, each [a] = [b]) 
// {[a=1, b=1]}

L'espressione sopra indicata è equivalente alla sintassi estesa seguente più difficile da interpretare:

List.Select( {[a=1, b=1], [a=2, b=4]}, (_) => _[a] = _[b]) 
// {[a=1, b=1]}

L'accesso ai campi non forza la valutazione di campi diversi da quelli a cui si accede, Ad esempio:

[A=error "a", B=1, C=error "c"][B]  // 1 
[A=error "a", B=error "b"][B]       // error "b"

Quando viene valutato l'operatore di accesso a un campo x[y], x[y]?, x[[y]] o x[[y]]?, tenere presente quanto segue:

  • Gli errori generati durante la valutazione dell'espressione x vengono propagati.

  • Gli errori generati durante la valutazione del campo y sono associati in modo permanente al campo y, quindi propagati. Eventuali accessi futuri al campo y genereranno un errore identico.

  • L'espressione x produce un valore di record o tabella oppure viene generato un errore.

  • Se l'identificatore y denomina un campo che non esiste in x, viene generato un errore con il codice motivo "Expression.Error" a meno che non venga usata la forma dell'operatore facoltativo ...?, nel qual caso viene restituito il valore null.

Nessun campo di x diverso da quello denominato da y viene valutato durante il processo di accesso al campo.

Operatore di metadati

Il record di metadati per un valore viene modificato usando l'operatore meta (x meta y).

metadata-expression:
      unary-expression
      unary-expression
meta unary-expression

L'esempio seguente costruisce un valore di testo con un record di metadati usando l'operatore meta e quindi accede al record di metadati del valore risultante usando Value.Metadata:

Value.Metadata( "Mozart" meta [ Rating = 5 ] ) 
// [Rating = 5 ]
Value.Metadata( "Mozart" meta [ Rating = 5 ] )[Rating] 
// 5

Quando si applicano i metadati che combinano l'operatore x meta y, tenere presente quanto segue:

  • Gli errori generati durante la valutazione delle espressioni x o y vengono propagati.

  • L'espressione y deve essere un record, altrimenti viene generato un errore con il codice motivo "Expression.Error".

  • Il record di metadati risultante è il record di metadati di x unito con y. Per la semantica del merge di record, vedere Unione di record.

  • Il valore risultante è il valore dell'espressione x, senza i metadati, a cui è collegato il record di metadati appena calcolato.

È possibile usare le funzioni della libreria standard Value.RemoveMetadata e Value.ReplaceMetadata per rimuovere tutti i metadati da un valore e sostituire i metadati di un valore (invece di unire i metadati nei metadati eventualmente esistenti). Le espressioni seguenti sono equivalenti:

x meta y  
Value.ReplaceMetadata(x, Value.Metadata(x) & y) 
Value.RemoveMetadata(x) meta (Value.Metadata(x) & y)

Operatori di uguaglianza

L'operatore di uguaglianza = viene usato per determinare se due valori sono uguali. L'operatore di disuguaglianza <> viene usato per determinare se due valori non sono uguali.

equality-expression:
      relational-expression
      relational-expression
= equality-expression
      relational-expression
<> equality-expression

Ad esempio:

1 = 1            // true 
1 = 2            // false 
1 <> 1           // false 
1 <> 2           // true 
null = true      // false 
null = null      // true

I metadati non fanno parte del confronto di uguaglianza o disuguaglianza, Ad esempio:

(1 meta [ a = 1 ]) = (1 meta [ a = 2 ]) // true 
(1 meta [ a = 1 ]) = 1                  // true

Quando si applicano gli operatori di uguaglianza x = y e x <> y, tenere presente quanto segue:

  • Gli errori generati durante la valutazione delle espressioni x o y vengono propagati.

  • L'operatore = ha come risultato true se i valori sono uguali; in caso contrario, false.

  • L'operatore <> ha come risultato false se i valori sono uguali; in caso contrario, true.

  • I record di metadati non sono inclusi nel confronto.

  • Se i valori prodotti dalla valutazione delle espressioni x e y non sono dello stesso tipo, i valori non sono uguali.

  • Se i valori prodotti dalla valutazione delle espressioni x e y sono dello stesso tipo, esistono regole specifiche per determinare se sono uguali, come definito di seguito.

  • La formula seguente è sempre vera:

    (x = y) = not (x <> y)

Gli operatori di uguaglianza sono definiti per i tipi seguenti:

  • Il valore null è uguale solo a se stesso.
    null = null    // true 
    null = true    // false 
    null = false   // false
  • I valori logici true e false sono uguali a se stessi, Ad esempio:
    true = true      // true 
    false = false    // true 
    true = false     // false 
    true = 1         // false
  • I numeri vengono confrontati con la precisione specificata:

    • Se uno dei due numeri è #nan, i numeri non sono uguali.

    • Quando nessuno dei due numeri è #nan, i numeri vengono confrontati usando un confronto bit per bit del valore numerico.

    • #nan è l'unico valore non uguale a se stesso.

      Ad esempio:

        1 = 1,              // true 
        1.0 = 1             // true 
        2 = 1               // false 
        #nan = #nan         // false 
        #nan <> #nan        // true
  • Due durate sono uguali se rappresentano lo stesso numero di cicli da 100 nanosecondi.

  • Due ore sono uguali se gli ordini di grandezza delle parti (ora, minuto, secondo) sono uguali.

  • Due date sono uguali se gli ordini di grandezza delle parti (anno, mese, giorno) sono uguali.

  • Due valori di data/ora sono uguali se gli ordini di grandezza delle parti (anno, mese, giorno, ora, minuto, secondo) sono uguali.

  • Due fusi orari sono uguali se i valori di data/ora UTC corrispondenti sono uguali. Per ottenere la data/ora UTC corrispondente, l'offset di ore/minuti viene sottratto dal componente data/ora del fuso orario.

  • Due valori di testo sono uguali se, usando un confronto ordinale, con distinzione tra maiuscole e minuscole e senza distinzione di impostazioni cultura, hanno la stessa lunghezza e caratteri uguali nelle posizioni corrispondenti.

  • Due valori di elenco sono uguali se si verificano tutte le condizioni seguenti:

    • Entrambi gli elenchi contengono lo stesso numero di elementi.

    • I valori di ogni elemento corrispondente a livello di posizione negli elenchi sono uguali. Ciò significa che non solo gli elenchi devono contenere elementi uguali, ma gli elementi devono anche essere nello stesso ordine.

      Ad esempio:

        {1, 2} = {1, 2}     // true 
        {2, 1} = {1, 2}     // false 
        {1, 2, 3} = {1, 2}  // false
      
  • Due record sono uguali se si verificano tutte le condizioni seguenti:

    • Il numero di campi è lo stesso.

    • Ogni nome di campo di un record è presente anche nell'altro record.

    • Il valore di ogni campo di un record è uguale al campo con lo stesso nome nell'altro record.

      Ad esempio:

        [ 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
      
  • Due tabelle sono uguali se si verificano tutte le condizioni seguenti:

    • Il numero di colonne è lo stesso.

    • Ogni nome di colonna in una tabella è presente anche nell'altra tabella.

    • Il numero di righe è lo stesso.

    • Ogni riga ha valori uguali nelle celle corrispondenti.

      Ad esempio:

        #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
      
  • Un valore di funzione è uguale a se stesso, ma può essere uguale o meno a un altro valore di funzione. Se due valori di funzione sono considerati uguali, si comporteranno in modo identico quando vengono richiamati.

    Due valori di funzione specificati avranno sempre la stessa relazione di uguaglianza.

  • Un valore di tipo è uguale a se stesso, ma può essere uguale o meno a un altro valore di tipo. Se due valori di tipo sono considerati uguali, si comporteranno in modo identico quando ne viene verificata la conformità tramite query.

    Due valori di tipo specificati avranno sempre la stessa relazione di uguaglianza.

Operatori relazionali

Gli operatori <, >, <= e >= sono detti operatori relazionali.

relational-expression:
      additive-expression
      additive-expression
< relational-expression
      additive-expression
> relational-expression
      additive-expression
<= relational-expression
      additive-expression
>= relational-expression

Questi operatori vengono usati per determinare la relazione di ordinamento relativa tra due valori, come illustrato nella tabella seguente:

Operazione Risultato
x < y true se x è minore di y; in caso contrario, false
x > y true se x è maggiore di y; in caso contrario, false
x <= y true se x è minore o uguale a y; in caso contrario, false
x >= y true se x è maggiore o uguale a y; in caso contrario, false

Ad esempio:

0 <= 1            // true 
null < 1          // null 
null <= null      // null 
"ab" < "abc"      // true 
#nan >= #nan      // false  
#nan <= #nan      // false

Quando si valuta un'espressione contenente gli operatori relazionali, tenere presente quanto segue:

  • Gli errori generati durante la valutazione delle espressioni dell'operando x o y vengono propagati.

  • I valori prodotti dalla valutazione di entrambe le espressioni x e y devono essere un valore binario, data, data/ora, fuso orario, durata, logico, numero, null, testo o ora. In caso contrario, viene generato un errore con il codice motivo "Expression.Error".

  • Entrambi gli operandi devono essere dello stesso tipo di valore o null. In caso contrario, viene generato un errore con il codice motivo "Expression.Error".

  • Se uno o entrambi gli operandi sono null, il risultato è il valore null.

  • Due file binari vengono confrontati byte per byte.

  • Due date vengono confrontate confrontando le parti degli anni e, se uguali, le parti dei mesi e, se uguali, le parti dei giorni.

  • Due valori di data/ora vengono confrontati confrontando le parti degli anni e, se uguali, le parti dei mesi e, se uguali, le parti dei giorni e, se uguali, le parti delle ore e, se uguali, le parti dei minuti e, se uguali, le parti dei secondi.

  • Due fusi orari vengono confrontati normalizzandoli in UTC sottraendo l'offset di ora/minuto e confrontando quindi i componenti di data/ora.

  • Due durate vengono confrontate in base al numero totale di cicli da 100 nanosecondi rappresentato.

  • Due logiche vengono confrontate in modo che true sia considerato maggiore di false.

  • Due numeri x e y vengono confrontati in base alle regole dello standard IEEE 754:

    • Se uno degli operandi è #nan, il risultato è false per tutti gli operatori relazionali.

    • Quando nessuno degli operandi è #nan, gli operatori confrontano i valori dei due operandi a virgola mobile rispetto all'ordinamento -∞ < -max < ... < -min < -0.0 = +0.0 < +min < ... < +max < +∞ dove min e max sono i valori finiti positivi più piccoli e più grandi che possono essere rappresentati. I nomi M per -∞ e +∞ sono -#infinity e #infinity.

      Gli effetti più importanti di questo ordinamento sono:

      • Gli zeri negativi e positivi sono considerati uguali.

      • Un valore -#infinity è considerato minore di tutti gli altri valori numerici, ma uguale a un altro -#infinity.

      • Un valore #infinity è considerato maggiore di tutti gli altri valori numerici, ma uguale a un altro #infinity.

  • Due testi vengono confrontati usando un confronto ordinale carattere per carattere, con distinzione tra maiuscole e minuscole e senza distinzione tra impostazioni cultura.

  • Due ore vengono confrontate confrontando le parti delle ore e, se uguali, le parti dei minuti e, se uguali, le parti dei secondi.

Operatori logici condizionali

Gli operatori and e or sono detti operatori logici condizionali.

logical-or-expression:
      logical-and-expression
logical-and-expression
or logical-or-expression
logical-and-expression:
      is-expression
      is-expression
and logical-and-expression

L'operatore or restituisce true quando almeno uno degli operandi è true. L'operando di destra viene valutato solo se l'operando di sinistra non è true.

L'operatore and restituisce false quando almeno uno degli operandi è false. L'operando di destra viene valutato solo se l'operando di sinistra non è false.

Le tabelle di veridicità per gli operatori or e and sono illustrate di seguito, con il risultato della valutazione dell'espressione dell'operando di sinistra sull'asse verticale e il risultato della valutazione dell'espressione dell'operando di destra sull'asse orizzontale.

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

Quando si valuta un'espressione contenente gli operatori logici condizionali, tenere presente quanto segue:

  • Gli errori generati durante la valutazione delle espressioni x o y vengono propagati.

  • Gli operatori logici condizionali vengono definiti sui tipi logical e null. Se i valori degli operandi non sono di tali tipi, viene generato un errore con il codice motivo "Expression.Error".

  • Il risultato è un valore logico.

  • Nell'espressione x o y l'espressione y verrà valutata solo se x non restituisce true.

  • Nell'espressione x e y l'espressione y verrà valutata solo se x non restituisce false.

Le ultime due proprietà assegnano agli operatori logici condizionali la qualifica di "condizionale". Le proprietà vengono definite anche di "corto circuito". Queste proprietà sono utili per scrivere predicati controllati compatti. Le espressioni seguenti, ad esempio, sono equivalenti:

d <> 0 and n/d > 1 if d <> 0 then n/d > 1 else false

Operatori aritmetici

Gli operatori +, -, * e / sono gli operatori aritmetici.

additive-expression:
      multiplicative-expression
      additive-expression
+ multiplicative-expression
      additive-expression
- multiplicative-expression
multiplicative-expression:
      metadata-expression
      multiplicative-expression
* metadata-expression
      multiplicative-expression
/ metadata-expression

Precision

I numeri in M vengono archiviati usando diverse rappresentazioni per conservare il maggior numero possibile di informazioni sui numeri provenienti da svariate origini. I numeri vengono solo convertiti da una rappresentazione a un'altra in base alle esigenze tramite gli operatori applicati. Sono supportate due precisioni in M:

Precision semantica
Precision.Decimal Rappresentazione decimale a 128 bit con un intervallo compreso tra ±1.0 x 10-28 e ±7.9 x 1028 e 28-29 cifre significative.
Precision.Double Rappresentazione scientifica con mantissa ed esponente, conforme allo standard aritmetico IEEE 754 a precisione doppia a 64 bit IEEE 754-2008.

Le operazioni aritmetiche vengono eseguite scegliendo una precisione, convertendo entrambi gli operandi in tale precisione (se necessario), quindi eseguendo l'operazione effettiva e infine restituendo un numero nella precisione scelta.

Gli operatori aritmetici predefiniti (+, -, *, /) usano la precisione doppia. È possibile usare le funzioni della libreria standard (Value.Add, Value.Subtract, Value.Multiply, Value.Divide) per richiedere queste operazioni usando un modello di precisione specifico.

  • Nessun overflow numerico è possibile: #infinity o -#infinity rappresentano valori di ordini di grandezza troppo elevati per essere rappresentati.

  • Nessun underflow numerico è possibile: 0 e -0 rappresentano valori di ordini di grandezza troppo piccoli per essere rappresentati.

  • Il valore speciale IEEE 754 #nan (NaN, non un numero) viene usato per i casi aritmeticamente non validi, ad esempio una divisione di zero per zero.

  • La conversione da precisione decimale a doppia viene eseguita arrotondando i numeri decimali al valore doppio equivalente più vicino.

  • La conversione da precisione doppia a decimale viene eseguita arrotondando i numeri doppi al valore decimale equivalente più vicino e, se necessario, tramite overflow ai valori #infinity o -#infinity.

operatore di addizione

L'interpretazione dell'operatore di addizione (x + y) dipende dal tipo di valore delle espressioni x e y valutate, come indicato di seguito:

x y Risultato Interpretazione
type number type number type number Somma numerica
type number null null
null type number null
type duration type duration type duration Somma numerica degli ordini di grandezza
type duration null null
null type duration null
type datetime type duration type datetime Offset di datetime in base alla durata
type duration type datetime type datetime
type datetime null null
null type datetime null

Nella tabella type datetime sta per qualsiasi type date, type datetime, type datetimezone, o type time. Quando si aggiungono una durata e un valore di un tipo datetime, il valore risultante è dello stesso tipo.

Per combinazioni di valori diverse da quelle elencate nella tabella, viene generato un errore con il codice motivo "Expression.Error". Ogni combinazione viene trattata nelle sezioni seguenti.

Gli errori generati durante la valutazione di uno degli operandi vengono propagati.

Somma numerica

La somma di due numeri viene calcolata usando l'operatore di addizione, che produce un numero.

Ad esempio:

1 + 1             // 2 
#nan + #infinity  // #nan

L'operatore di addizione + sui numeri usa la precisione doppia. La funzione della libreria standard Value.Add può essere usata per specificare la precisione decimale. Quando si calcola una somma di numeri, tenere presente quanto segue:

  • La somma a precisione doppia viene calcolata in base alle regole aritmetiche IEEE 754 a precisione doppia binarie a 64 bit IEEE 754-2008. La tabella seguente elenca i risultati di tutte le possibili combinazioni di valori finiti diversi da zero, zeri, infiniti e non numeri. Nella tabella x e y sono valori finiti diversi da zero e z è il risultato di x + y. Se x e y hanno lo stesso ordine di grandezza ma segni opposti, z è zero positivo. Se x + y è troppo grande per essere rappresentato nel tipo di destinazione, z è un valore infinito con lo stesso segno di x + y.

    + y +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
  • La somma a precisione decimale viene calcolata senza perdere la precisione. La scala del risultato è la più grande tra le scale dei due operandi.

Somma delle durate

La somma di due durate è la durata che rappresenta la somma del numero di cicli da 100 nanosecondi rappresentati dalle durate, Ad esempio:

#duration(2,1,0,15.1) + #duration(0,1,30,45.3) 
// #duration(2, 2, 31, 0.4)

Offset di datetime in base alla durata

Un valore datetime x e una durata y possono essere sommati usando x + y per calcolare un nuovo valore datetime la cui distanza da x su una sequenza temporale lineare è esattamente l'ordine di grandezza di y. In questo caso datetime sta per Date, DateTime, DateTimeZone o Time e un risultato non Null sarà dello stesso tipo. L'offset di datetime in base alla durata può essere calcolato come segue:

  • Se vengono specificati i giorni di datetime a partire dal valore di periodo, costruire un nuovo valore datetime con le informazioni seguenti:

    • Calcolare un nuovo valore "giorni dal periodo" equivalente alla divisione della grandezza di y per il numero di cicli da 100 nanosecondi in un periodo di 24 ore, troncando la parte decimale del risultato e aggiungendo questo valore ai giorni di x dal periodo.

    • Calcolare un nuovo valore "cicli da mezzanotte" equivalente all'aggiunta della grandezza di y ai cicli di x da mezzanotte, eseguendo il modulo del numero di cicli da 100 nanosecondi in un periodo di 24 ore. Se x non specifica un valore per i cicli dalla mezzanotte, si presume un valore pari a 0.

    • Copiare il valore di x per l'offset dei minuti dall'ora UTC non modificata.

  • Se non vengono specificati i giorni di datetime a partire dal valore di periodo, costruire un nuovo valore datetime con le informazioni seguenti specificate:

    • Calcolare un nuovo valore "cicli da mezzanotte" equivalente all'aggiunta della grandezza di y ai cicli di x da mezzanotte, eseguendo il modulo del numero di cicli da 100 nanosecondi in un periodo di 24 ore. Se x non specifica un valore per i cicli dalla mezzanotte, si presume un valore pari a 0.

    • Copiare i valori di x per i giorni dal periodo e l'offset dei minuti dall'ora UTC non modificata.

Gli esempi seguenti illustrano il calcolo della somma temporale assoluta quando datetime specifica i giorni dal periodo:

#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

L'esempio seguente illustra il calcolo dell'offset di datetime in base alla durata per un determinato periodo di tempo:

#time(8,0,0) + #duration(30,5,0,0) 
   //#time(13, 0, 0) 
   //13:00:00

operatore di sottrazione

L'interpretazione dell'operatore di sottrazione (x - y) dipende dal tipo del valore delle espressioni x e y valutate, come indicato di seguito:

x Y Risultato Interpretazione
type number type number type number Differenza numerica
type number null null
null type number null
type duration type duration type duration Differenza numerica degli ordini di grandezze
type duration null null
null type duration null
type datetime type datetime type duration Durata tra valori datetime
type datetime type duration type datetime Offset di datetime in base alla durata negata
type datetime null null
null type datetime null

Nella tabella type datetime sta per qualsiasi type date, type datetime, type datetimezone, o type time. Quando si sottrae una durata da un valore di un tipo datetime, il valore risultante è dello stesso tipo.

Per combinazioni di valori diverse da quelle elencate nella tabella, viene generato un errore con il codice motivo "Expression.Error". Ogni combinazione viene trattata nelle sezioni seguenti.

Gli errori generati durante la valutazione di uno degli operandi vengono propagati.

Differenza numerica

La differenza tra due numeri viene calcolata usando l'operatore di sottrazione, che produce un numero. Ad esempio:

1 - 1                // 0 
#nan - #infinity     // #nan

L'operatore di sottrazione - sui numeri usa la precisione doppia. La funzione della libreria standard Value.Subtract può essere usata per specificare la precisione decimale. Quando si calcola una differenza tra numeri, tenere presente quanto segue:

  • La differenza a precisione doppia viene calcolata in base alle regole aritmetiche IEEE 754 a precisione doppia binarie a 64 bit IEEE 754-2008. La tabella seguente elenca i risultati di tutte le possibili combinazioni di valori finiti diversi da zero, zeri, infiniti e non numeri. Nella tabella x e y sono valori finiti diversi da zero e z è il risultato di x - y. Se x e y sono uguali, z è zero positivo. Se x - y è troppo grande per essere rappresentato nel tipo di destinazione, z è un valore infinito con lo stesso segno di x - y.

    - y +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
  • La differenza a precisione decimale viene calcolata senza perdere la precisione. La scala del risultato è la più grande tra le scale dei due operandi.

Differenza tra le durate

La differenza di due durate è la durata che rappresenta la differenza tra il numero di cicli da 100 nanosecondi rappresentati da ogni durata, Ad esempio:

#duration(1,2,30,0) - #duration(0,0,0,30.45) 
// #duration(1, 2, 29, 29.55)

Offset di datetime in base alla durata negata

Un valore datetime x e una durata y possono essere sottratti usando x - y per calcolare un nuovo valore datetime. In questo caso datetime sta per date, datetime, datetimezone o time. Il valore datetime risultante ha una distanza da x su una sequenza temporale lineare che corrisponde esattamente alla grandezza di y, nella direzione opposta al segno di y. La sottrazione di durate positive produce risultati che tornano indietro nel tempo relativamente a x, mentre la sottrazione di valori negativi produce risultati che vanno avanti nel 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

Durata tra due valori datetime

È possibile sottrarre due valori datetime t e u usando t - u per calcolare la durata tra di essi. In questo caso datetime sta per date, datetime, datetimezone o time. La durata ottenuta sottraendo u da t deve restituire t se aggiunta 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

La sottrazione t - u quando u > t restituisce una durata negativa:

#time(01,30,00) - #time(08,00,00) 
// #duration(0, -6, -30, 0)

Quando si sottraggono due valori datetime usando t - u, tenere presente quanto segue:

  • u + (t - u) = t

operatore di moltiplicazione

L'interpretazione dell'operatore di moltiplicazione (x * y) dipende dal tipo di valore delle espressioni x e y valutate, come indicato di seguito:

X Y Risultato Interpretazione
type number type number type number Prodotto numerico
type number null null
null type number null
type duration type number type duration Multiplo della durata
type number type duration type duration Multiplo della durata
type duration null null
null type duration null

Per combinazioni di valori diverse da quelle elencate nella tabella, viene generato un errore con il codice motivo "Expression.Error". Ogni combinazione viene trattata nelle sezioni seguenti.

Gli errori generati durante la valutazione di uno degli operandi vengono propagati.

Prodotto numerico

Il prodotto di due numeri viene calcolato usando l'operatore di moltiplicazione, che produce un numero. Ad esempio:

2 * 4                // 8 
6 * null             // null 
#nan * #infinity     // #nan

L'operatore di moltiplicazione * sui numeri usa la precisione doppia. La funzione della libreria standard Value.Multiply può essere usata per specificare la precisione decimale. Quando si calcola un prodotto di numeri, tenere presente quanto segue:

  • Il prodotto a precisione doppia viene calcolato in base alle regole aritmetiche IEEE 754 a precisione doppia binarie a 64 bit IEEE 754-2008. La tabella seguente elenca i risultati di tutte le possibili combinazioni di valori finiti diversi da zero, zeri, infiniti e non numeri. Nella tabella x e y sono valori finiti positivi. z è il risultato di x * y. Se il risultato è troppo grande per il tipo di destinazione, z è infinito. Se il risultato è troppo piccolo per il tipo di destinazione, z è pari a 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
  • Il prodotto a precisione decimale viene calcolato senza perdere la precisione. La scala del risultato è la più grande tra le scale dei due operandi.

Multipli di durate

Il prodotto di una durata e di un numero è uguale alla durata che rappresenta il numero di cicli da 100 nanosecondi rappresentati dall'operando della durata moltiplicato per l'operando del numero, Ad esempio:

#duration(2,1,0,15.1) * 2 
// #duration(4, 2, 0, 30.2)

operatore di divisione

L'interpretazione dell'operatore di divisione (x / y) dipende dal tipo di valore delle espressioni x e y valutate, come indicato di seguito:

X Y Risultato Interpretazione
type number type number type number Quoziente numerico
type number null null
null type number null
type duration type number type duration Frazione di durata
type duration type duration type number Quoziente numerico delle durate
type duration null null
null type duration null

Per combinazioni di valori diverse da quelle elencate nella tabella, viene generato un errore con il codice motivo "Expression.Error". Ogni combinazione viene trattata nelle sezioni seguenti.

Gli errori generati durante la valutazione di uno degli operandi vengono propagati.

Quoziente numerico

Il quoziente di due numeri viene calcolato usando l'operatore di divisione, che produce un numero, Ad esempio:

8 / 2               // 4 
8 / 0               // #infinity 
0 / 0               // #nan 
0 / null            // null 
#nan / #infinity    // #nan

L'operatore di divisione / sui numeri usa la precisione doppia. La funzione della libreria standard Value.Divide può essere usata per specificare la precisione decimale. Quando si calcola un quoziente di numeri, tenere presente quanto segue:

  • Il quoziente a precisione doppia viene calcolato in base alle regole aritmetiche IEEE 754 a precisione doppia binarie a 64 bit IEEE 754-2008. La tabella seguente elenca i risultati di tutte le possibili combinazioni di valori finiti diversi da zero, zeri, infiniti e non numeri. Nella tabella x e y sono valori finiti positivi. z è il risultato di x / y. Se il risultato è troppo grande per il tipo di destinazione, z è infinito. Se il risultato è troppo piccolo per il tipo di destinazione, z è pari a 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
  • La somma a precisione decimale viene calcolata senza perdere la precisione. La scala del risultato è la più grande tra le scale dei due operandi.

Quoziente di durate

Il quoziente di due durate è il numero che rappresenta il quoziente del numero di cicli da 100 nanosecondi rappresentati dalle durate, Ad esempio:

#duration(2,0,0,0) / #duration(0,1,30,0) 
// 32

Durate ridimensionate

Il quoziente di una durata x e di un numero y è uguale alla durata che rappresenta il quoziente del numero di cicli da 100 nanosecondi rappresentati dalla durata x e dal numero y, Ad esempio:

#duration(2,0,0,0) / 32 
// #duration(0,1,30,0)

Combinazione di strutture

L'operatore di combinazione (x & y) viene definito nei tipi di valori seguenti:

X Y Risultato Interpretazione
type text type text type text Concatenation
type text null null
null type text null
type date type time type datetime Unire
type date null null
null type time null
type list type list type list Concatenation
type record type record type record Unire
type table type table type table Concatenation

Concatenation

Due valori di testo, due valori di elenco o due valori di tabelle possono essere concatenati usando x & y.

L'esempio seguente illustra la concatenazione di valori di testo:

"AB" & "CDE"     // "ABCDE"

L'esempio seguente illustra la concatenazione di elenchi:

{1, 2} & {3}     // {1, 2, 3}

Quando si concatenano due valori usando x & y, tenere presente quanto segue:

  • Gli errori generati durante la valutazione delle espressioni x o y vengono propagati.

  • Se un elemento di x o y contiene un errore, non viene propagato alcun errore.

  • Il risultato della concatenazione di due valori di testo è un valore di testo che contiene il valore di x seguito immediatamente da y. Se uno degli operandi è Null e l'altro è un valore di testo, il risultato è Null.

  • Il risultato della concatenazione di due elenchi è un elenco che contiene tutti gli elementi di x seguiti da tutti gli elementi di y.

  • Il risultato della concatenazione di due tabelle è una tabella che contiene l'unione delle colonne delle due tabelle dell'operando. L'ordinamento delle colonne di x viene mantenuto, seguito dalle colonne visualizzate solo in y, che mantengono il proprio ordinamento relativo. Per le colonne visualizzate solo in uno degli operandi, viene usato null per inserire i valori delle celle per l'altro operando.

Unire

Unione di record

È possibile unire due record usando x & y, che produce un record che include i campi sia di x che di y.

Gli esempi seguenti illustrano l'unione di record:

[ x = 1 ] & [ y = 2 ]                // [ x = 1, y = 2 ] 
[ x = 1, y = 2 ] & [ x = 3, z = 4 ]  // [ x = 3, y = 2, z = 4 ]

Quando si uniscono due record usando x + y, tenere presente quanto segue:

  • Gli errori generati durante la valutazione delle espressioni x o y vengono propagati.

  • Se un campo viene visualizzato sia in x che in y, viene usato il valore di y.

  • L'ordine dei campi nel record risultante è quello di x, seguiti dai campi di y che non fanno parte di x, nello stesso ordine in cui vengono visualizzati in y.

  • L'unione di record non comporta la valutazione dei valori.

  • Non vengono generati errori perché un campo contiene un errore.

  • Il risultato è un record.

Unione di data e ora

Una data x può essere unita a un'ora y usando x & y, che produce un valore datetime che combina le parti sia di x che di y.

L'esempio seguente illustra l'unione di una data e di un'ora:

#date(2013,02,26) & #time(09,17,00) 
// #datetime(2013,02,26,09,17,00)

Quando si uniscono due record usando x + y, tenere presente quanto segue:

  • Gli errori generati durante la valutazione delle espressioni x o y vengono propagati.

  • Il risultato è un valore datetime.

Operatori unari

Gli operatori +, - e not sono operatori unari.

unary-expression:
      type-expression

      + unary expression
      - unary expression
      not unary expression

Operatore più unario

L'operatore unario più (+x) viene definito per i tipi di valori seguenti:

X Risultato Interpretazione
type number type number Più unario
type duration type duration Più unario
null `null

Per gli altri valori, viene generato un errore con il codice motivo "Expression.Error".

L'operatore unario più consente di applicare un segno + a un numero, a un valore datetime o a un valore Null. Il risultato è quello stesso valore, Ad esempio:

+ - 1                 // -1 
+ + 1                 // 1 
+ #nan                // #nan 
+ #duration(0,1,30,0) // #duration(0,1,30,0)

Quando si valuta l'operatore unario più +x, tenere presente quanto segue:

  • Gli errori generati durante la valutazione di x vengono propagati.

  • Se il risultato della valutazione di x non è un valore numerico, viene generato un errore con il codice motivo "Expression.Error".

Operatore meno unario

L'operatore unario meno (-x) viene definito per i tipi di valori seguenti:

X Risultato Interpretazione
type number type number Negazione
type duration type duration Negazione
null null

Per gli altri valori, viene generato un errore con il codice motivo "Expression.Error".

L'operatore unario meno viene usato per cambiare il segno di un numero o di una durata, Ad esempio:

- (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)

Quando si valuta l'operatore unario meno -x, tenere presente quanto segue:

  • Gli errori generati durante la valutazione di x vengono propagati.

  • Se l'espressione è un numero, il risultato è il valore numerico dell'espressione x con il segno cambiato. Se il valore non è un numero, neanche il risultato è un numero.

Operatore di negazione logica

L'operatore di negazione logica (not) viene definito per i tipi di valori seguenti:

X Risultato Interpretazione
type logical type logical Negazione
null null

Questo operatore calcola l'operazione not logica su un valore logico specificato, Ad esempio:

not true             // false 
not false            // true 
not (true and true)  // false

Quando si valuta l'operatore di negazione logica not x, tenere presente quanto segue:

  • Gli errori generati durante la valutazione di x vengono propagati.

  • Il valore prodotto dalla valutazione dell'espressione x deve essere un valore logico oppure deve essere generato un errore con il codice motivo "Expression.Error". Se il valore è true, il risultato è false. Se l'operando è false, il risultato è true.

Il risultato è un valore logico.

Operatori di tipo

Gli operatori is e as sono noti come operatori di tipo.

Operatore di compatibilità del tipo

L'operatore di compatibilità del tipo x is y è definito per i tipi di valori seguenti:

X Y Risultato
type any nullable-primitive-type type logical

L'espressione x is y restituisce true se il tipo ascritto di x è compatibile con y e restituisce false se il tipo ascritto di x non è compatibile con y. y deve essere un tipo nullable-primitivetype.

is-expression:
      as-expression
      is-expression
is nullable-primitive-type
nullable-primitive-type:

      nullableopt primitive-type

La compatibilità del tipo, supportata dall'operatore is, è un subset della compatibilità del tipo generale e viene definita usando le regole seguenti:

  • Se x è Null, è compatibile se y è il tipo any, il tipo nullo un tipo nullable.

  • Se x è diverso da Null, è compatibile se il tipo primitivo di x è lo stesso di y.

Quando si valuta l'espressione x is y, tenere presente quanto segue:

  • Un errore generato durante la valutazione dell'espressione x viene propagato.

Operatore di asserzione del tipo

L'operatore di asserzione del tipo x as y è definito per i tipi di valori seguenti:

X Y Risultato
type any nullable-primitive-type type any

L'espressione x as y asserisce che il valore x è compatibile con y in base all'operatore is. Se non è compatibile, viene generato un errore. y deve essere un tipo nullable-primitive-type.

as-expression:
      equality-expression
      as-expression
as nullable-primitive-type

L'espressione x as y viene valutata nel modo seguente:

  • Viene eseguita una verifica della compatibilità del tipo x is y e l'asserzione restituisce x non modificato se il test ha esito positivo.

  • Se la verifica della compatibilità ha esito negativo, viene generato un errore con il codice motivo "Expression.Error".

Esempi:

1 as number               // 1 
"A" as number             // error 
null as nullable number   // null

Quando si valuta l'espressione x as y, tenere presente quanto segue:

  • Un errore generato durante la valutazione dell'espressione x viene propagato.

Operatore Coalesce

L'operatore coalesce ?? restituisce il risultato dell'operando sinistro se non è Null; in caso contrario, restituirà il risultato dell'operando destro. L'operando di destra viene valutato solo se l'operando di sinistra è null.