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 numeroy
, l'elemento dell'elencox
nella posizioney
. 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 numeroy
, la riga della tabellax
nella posizioney
. 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 recordy
, la riga della tabellax
che corrisponde ai valori di campo del recordy
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
oy
vengono propagati.L'espressione
x
produce un elenco o un valore di tabella.L'espressione
y
produce un valore numerico o, sex
produce un valore di tabella, un valore di record.Se
y
produce un valore numerico e il valore diy
è negativo, viene generato un errore con il codice motivo"Expression.Error"
.Se
y
produce un valore numerico e il valore diy
è maggiore o uguale al conteggio dix
, viene generato un errore con il codice motivo"Expression.Error"
a meno che non venga usata la forma dell'operatore facoltativox{y}?
, nel qual caso viene restituito il valorenull
.Se
x
produce un valore di tabella ey
produce un valore di record e non sono presenti corrispondenze pery
inx
, viene generato un errore con il codice motivo"Expression.Error"
a meno che non venga usata la forma dell'operatore facoltativox{y}?
, nel qual caso viene restituito il valorenull
.Se
x
produce un valore di tabella ey
produce un valore di record e sono presenti più corrispondenze pery
inx
, 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 campoy
, quindi propagati. Eventuali accessi futuri al campoy
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 inx
, 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 valorenull
.
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
oy
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 cony
. 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
oy
vengono propagati.L'operatore
=
ha come risultatotrue
se i valori sono uguali; in caso contrario,false
.L'operatore
<>
ha come risultatofalse
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
ey
non sono dello stesso tipo, i valori non sono uguali.Se i valori prodotti dalla valutazione delle espressioni
x
ey
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
efalse
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
oy
vengono propagati.I valori prodotti dalla valutazione di entrambe le espressioni
x
ey
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 valorenull
.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 difalse
.Due numeri
x
ey
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
oy
vengono propagati.Gli operatori logici condizionali vengono definiti sui tipi
logical
enull
. 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
oy
l'espressioney
verrà valutata solo sex
non restituiscetrue
.Nell'espressione
x
ey
l'espressioney
verrà valutata solo sex
non restituiscefalse
.
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
ey
sono valori finiti diversi da zero ez
è il risultato dix + y
. Sex
ey
hanno lo stesso ordine di grandezza ma segni opposti,z
è zero positivo. Sex + y
è troppo grande per essere rappresentato nel tipo di destinazione,z
è un valore infinito con lo stesso segno dix + 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
ey
sono valori finiti diversi da zero ez
è il risultato dix - y
. Sex
ey
sono uguali,z
è zero positivo. Sex - y
è troppo grande per essere rappresentato nel tipo di destinazione,z
è un valore infinito con lo stesso segno dix - 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
ey
sono valori finiti positivi.z
è il risultato dix * 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
ey
sono valori finiti positivi.z
è il risultato dix / 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
oy
vengono propagati.Se un elemento di
x
oy
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 diy
.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 iny
, che mantengono il proprio ordinamento relativo. Per le colonne visualizzate solo in uno degli operandi, viene usatonull
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
oy
vengono propagati.Se un campo viene visualizzato sia in
x
che iny
, viene usato il valore diy
.L'ordine dei campi nel record risultante è quello di
x
, seguiti dai campi diy
che non fanno parte dix
, nello stesso ordine in cui vengono visualizzati iny
.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
oy
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:
nullable
opt 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 sey
è il tipoany
, il tiponull
o un tipo nullable.Se
x
è diverso da Null, è compatibile se il tipo primitivo dix
è lo stesso diy
.
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 restituiscex
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.