Typer
En typeverdi er en verdi som klassifiserer andre verdier. En verdi som klassifiseres etter en type, sies å samsvare med denne typen. M-typesystemet består av følgende typer typer:
Primitive typer, som klassifiserer primitive verdier (
binary
, ,date
,datetime
,datetimezone
,duration
,list
,logical
,null
,number
,record
,text
,type
time
) og inkluderer også en rekke abstrakte typer (function
,table
,any
oganynonnull
none
)Oppføringstyper som klassifiserer postverdier basert på feltnavn og verdityper
Listetyper som klassifiserer lister ved hjelp av en basistype for enkeltelement
Funksjonstyper som klassifiserer funksjonsverdier basert på typene parametere og returverdier
Tabelltyper som klassifiserer tabellverdier basert på kolonnenavn, kolonnetyper og nøkler
Nullverdityper, som klassifiserer verdien null i tillegg til alle verdiene klassifisert etter en basistype
Typetyper som klassifiserer verdier som er typer
Settet med primitive typer inkluderer typene primitive verdier og en rekke abstrakte typer, som er typer som ikke unikt klassifiserer verdier: function
, , table
, any
anynonnull
og none
. Alle funksjonsverdier samsvarer med den abstrakte typen function
, alle tabellverdier til den abstrakte typen table
, alle verdier til den abstrakte typen any
, alle verdier som ikke er null, til den abstrakte typen anynonnull
og ingen verdier i den abstrakte typen none
. Et uttrykk av typen none
må opphøye en feil eller mislykkes i å avslutte fordi ingen verdi kan produseres som samsvarer med typen none
. Vær oppmerksom på at primitive typer function
og table
er abstrakte fordi ingen funksjon eller tabell er direkte av disse typene, henholdsvis. Primitive typer record
og list
er ikke-abstrakte fordi de representerer en åpen post uten definerte felt og en liste av typen noen, henholdsvis.
Alle typer som ikke er medlemmer av det lukkede settet med primitive typer pluss deres nullbare kolleger, kalles samlet egendefinerte typer. Egendefinerte typer kan skrives ved hjelp av et type-expression
:
type-uttrykk:
primært uttrykk
type
primærtype
type:
primært uttrykk
primærtype
primærtype:
primitiv type
posttype
listetype
funksjonstype
tabelltype
nullbar-type
primitiv-type: én av
any anynonnull binary date datetime datetimezone duration function list logical
none null number record table text time type
Primitive typenavn er kontekstavhengige nøkkelord som bare gjenkjennes i en typekontekst . Bruken av parenteser i en typekontekst flytter grammatikken tilbake til en vanlig uttrykkskontekst, noe som krever bruk av typenøkkelordet for å flytte tilbake til en typekontekst. Hvis du for eksempel vil aktivere en funksjon i en typekontekst , kan parenteser brukes:
type nullable ( Type.ForList({type number}) )
// type nullable {number}
Parenteser kan også brukes til å få tilgang til en variabel der navnet kolliderer med et primitivt typenavn :
let record = type [ A = any ] in type {(record)}
// type {[ A = any ]}
Følgende eksempel definerer en type som klassifiserer en liste med tall:
type { number }
På samme måte definerer følgende eksempel en egendefinert type som klassifiserer poster med obligatoriske felt med navn X
og Y
hvis verdier er tall:
type [ X = number, Y = number ]
Den tilskrevne typen av en verdi hentes ved hjelp av standard bibliotekfunksjonen Value.Type, som vist i følgende eksempler:
Value.Type( 2 ) // type number
Value.Type( {2} ) // type list
Value.Type( [ X = 1, Y = 2 ] ) // type record
Operatoren is
brukes til å avgjøre om en verditype er kompatibel med en gitt type, som vist i følgende eksempler:
1 is number // true
1 is text // false
{2} is list // true
Operatoren as
kontrollerer om verdien er kompatibel med den angitte typen, og utløser en feil hvis den ikke er det. Ellers returnerer den opprinnelige verdien.
Value.Type( 1 as number ) // type number
{2} as text // error, type mismatch
Vær oppmerksom på at operatorene is
og as
operatorene bare godtar primitive typer som riktig operand. M gir ikke midler til å kontrollere verdier for samsvar med egendefinerte typer.
En type X
er kompatibel med en type Y
hvis og bare hvis alle verdier som samsvarer X
med også samsvarer Y
med . Alle typer er kompatible med typen any
, og ingen typer (men i none
seg selv) er kompatible med typen none
. Følgende graf viser kompatibilitetsrelasjonen. (Typekompatibilitet er refleksiv og transitiv. Det danner et gitter med typen any
som øverst og skriver inn none
som den nederste verdien.) Navnene på abstrakte typer angis i kursiv.
Følgende operatorer er definert for typeverdier:
Operator | Resultat |
---|---|
x = y |
Equal |
x <> y |
Not equal |
x ?? y |
Coalesce |
Den opprinnelige typen type verdier er den innebygde typen type
.
Typer i M-språket danner et usammenhengende hierarki som er forankret i typen any
, som er typen som klassifiserer alle verdier. Enhver M-verdi samsvarer med nøyaktig én primitiv undertype av any
. Det lukkede settet med primitive typer avledet fra type any
er som følger:
type null
, som klassifiserer nullverdien.type logical
, som klassifiserer verdiene sann og usann.type number
, som klassifiserer tallverdier.type time
, som klassifiserer tidsverdier.type date
, som klassifiserer datoverdier.type datetime
, som klassifiserer datetime-verdier.type datetimezone
, som klassifiserer datetimezone-verdier.type duration
, som klassifiserer varighetsverdier.type text
, som klassifiserer tekstverdier.type binary
, som klassifiserer binære verdier.type type
, som klassifiserer typeverdier.type list
, som klassifiserer listeverdier.type record
, som klassifiserer postverdier.type table
, som klassifiserer tabellverdier.type function
, som klassifiserer funksjonsverdier.type anynonnull
, som klassifiserer alle verdier unntatt null.type none
, som ikke klassifiserer noen verdier.
Typen any
er abstrakt, klassifiserer alle verdier i M, og alle typer i M er kompatible med any
. Variabler av typen any
kan bindes til alle mulige verdier. Siden any
det er abstrakt, kan det ikke tilskrives verdier – det vil si at ingen verdi er direkte av typen any
.
Alle verdier som er en liste, samsvarer med den innebygde typen list
, som ikke legger noen begrensninger på elementene i en listeverdi.
listetype:
{
elementtype }
elementtype:
type
Resultatet av evalueringen av en listetype er en listetypeverdi som har list
basistypen .
Følgende eksempler illustrerer syntaksen for deklarering av homogene listetyper:
type { number } // list of numbers type
{ record } // list of records type
{{ text }} // list of lists of text values
En verdi samsvarer med en listetype hvis verdien er en liste, og hvert element i denne listeverdien samsvarer med listetypens elementtype.
Elementtypen for en listetype angir en bundet verdi: Alle elementer i en samsvarsliste samsvarer med elementtypen.
Alle verdier som er en post, samsvarer med den innebygde typeposten, som ikke legger noen begrensninger på feltnavnene eller verdiene i en postverdi. En posttypeverdi brukes til å begrense settet med gyldige navn samt verditypene som har tillatelse til å knyttes til disse navnene.
posttype:
[
open-record- ]
[
velger feltspesifikasjonsliste ]
[
felt-spesifikasjon-liste , open-record- ]
feltspesifikasjonsliste:
feltspesifikasjon
feltspesifikasjonsliste for feltspesifikasjon,
feltspesifikasjon:
optional
opt field-name field-type-specificationopt
felttype-spesifikasjon:
=
felttype
felttype:
type
open-record-:
...
Resultatet av evalueringen av en posttype er en typeverdi som har basistypen record
.
Følgende eksempler illustrerer syntaksen for deklarering av posttyper:
type [ X = number, Y = number]
type [ Name = text, Age = number ]
type [ Title = text, optional Description = text ]
type [ Name = text, ... ]
Posttyper lukkes som standard, noe som betyr at flere felt som ikke finnes i feltspesifikke lister, ikke har tillatelse til å være til stede i samsvarende verdier. Inkludert openrecord-indikatoren i posttypen erklærer typen som skal være åpen, noe som tillater felt som ikke finnes i feltspesifikasjonslisten. Følgende to uttrykk tilsvarer:
type record // primitive type classifying all records
type [ ... ] // custom type classifying all records
En verdi samsvarer med en posttype hvis verdien er en post, og hver feltspesifikasjon i posttypen er oppfylt. En feltspesifikasjon er fornøyd hvis noen av følgende er sanne:
Det finnes et feltnavn som samsvarer med spesifikasjonens identifikator i posten, og den tilknyttede verdien samsvarer med spesifikasjonens type
Spesifikasjonen er merket som valgfri, og det finnes ingen tilsvarende feltnavn i posten
En samsvarsverdi kan inneholde feltnavn som ikke er oppført i feltspesifikasjonslisten hvis og bare hvis posttypen er åpen.
Enhver funksjonsverdi samsvarer med den primitive typen function
, som ikke legger noen begrensninger på typene av funksjonens formelle parametere eller funksjonens returverdi. En egendefinert funksjonstypeverdi brukes til å plassere typebegrensninger på signaturene til samsvarende funksjonsverdier.
funksjonstype:
function (
parameter-specification-listopt )
function-return-type
parameter-spesifikasjon-liste:
obligatorisk parameter-spesifikasjon-liste
required-parameter-specification-list ,
optional-parameter-specification-list
valgfri parameter-spesifikasjon-liste
obligatorisk parameter-spesifikasjon-liste:
obligatorisk parameter-spesifikasjon
obligatorisk parameter-spesifikasjon ,
obligatorisk-parameter-spesifikasjon-liste
obligatorisk parameter-spesifikasjon:
parameter-spesifikasjon
valgfri parameter-spesifikasjon-liste:
valgfri parameter-spesifikasjon
valgfri parameter-spesifikasjon ,
valgfritt-parameter-spesifikasjon-liste
valgfri parameter-spesifikasjon:
optional
parameter-spesifikasjon
parameter-spesifikasjon:
parametertype for parameternavn
funksjon-retur-type:
assertion
påstand:
as
nullable-primitive-type
Resultatet av evalueringen av en funksjonstype er en typeverdi som har basistypen function
.
Følgende eksempler illustrerer syntaksen for deklarering av funksjonstyper:
type function (x as text) as number
type function (y as number, optional z as text) as any
En funksjonsverdi samsvarer med en funksjonstype hvis returtypen for funksjonsverdien er kompatibel med funksjonstypens returtype, og hver parameterspesifikasjon av funksjonstypen er kompatibel med funksjonens posisjonsmessig tilhørende formelle parameter. En parameterspesifikasjon er kompatibel med en formell parameter hvis den angitte parametertypetypen er kompatibel med typen formell parameter, og parameterspesifikasjonen er valgfri hvis den formelle parameteren er valgfri.
Formelle parameternavn ignoreres med det formål å fastslå funksjonstypesamsamhold.
Hvis du angir en parameter som valgfri implisitt, kan typen nullstilles. Følgende oppretter identiske funksjonstyper:
type function (optional x as text) as any
type function (optional x as nullable text) as any
En tabelltypeverdi brukes til å definere strukturen til en tabellverdi.
tabelltype:
table
radtype
radtype:
[
velger feltspesifikasjonsliste ]
Resultatet av evalueringen av en tabelltype er en typeverdi som har basistypen table
.
Radtypen for en tabell angir kolonnenavnene og kolonnetypene i tabellen som en lukket posttype. Slik at alle tabellverdier samsvarer med typen table
, er radtypen type record
(den tomme åpne posttypen). Derfor er typetabell abstrakt fordi ingen tabellverdi kan ha typen table
radtype (men alle tabellverdier har en radtype som er kompatibel med typen table
radtype). Følgende eksempel viser konstruksjonen av en tabelltype:
type table [A = text, B = number, C = binary]
// a table type with three columns named A, B, and C
// of column types text, number, and binary, respectively
En tabelltypeverdi har også definisjonen av nøklene til en tabellverdi. En nøkkel er et sett med kolonnenavn. Maksimalt én nøkkel kan angis som primærnøkkelen for tabellen. (Innenfor M har tabellnøkler ingen semantisk betydning. Det er imidlertid vanlig for eksterne datakilder, for eksempel databaser eller OData-feeder, å definere nøkler over tabeller. Power Query bruker viktig informasjon til å forbedre ytelsen til avansert funksjonalitet, for eksempel sammenføyningsoperasjoner på tvers av kilder.)
Standard bibliotekfunksjoner Type.TableKeys
, Type.AddTableKey
og Type.ReplaceTableKeys
kan brukes til å hente nøklene til en tabelltype, legge til en nøkkel i en tabelltype og erstatte henholdsvis alle nøkler i en tabelltype.
Type.AddTableKey(tableType, {"A", "B"}, false)
// add a non-primary key that combines values from columns A and B
Type.ReplaceTableKeys(tableType, {})
// returns type value with all keys removed
For alle type T
kan en variant som kan nullstilles, utledes ved hjelp av nulltype:
nullbar type:
nullable
type
Resultatet er en abstrakt type som tillater verdier av typen T eller verdien null
.
42 is nullable number // true null is
nullable number // true
Ascription av type nullable
T reduserer til ascription av type null
eller type
T. (Husk at nullbare typer er abstrakte, og ingen verdi kan være direkte av abstrakt type.)
Value.Type(42 as nullable number) // type number
Value.Type(null as nullable number) // type null
Standard bibliotekfunksjoner Type.IsNullable
og Type.NonNullable
kan brukes til å teste en type for nullabilitet og for å fjerne nullabilitet fra en type.
Følgende sperring (for alle type T
):
type T
er kompatibel medtype nullable T
Type.NonNullable(type T)
er kompatibel medtype T
Følgende tilsvarer parvis (for alle type T
):
type nullable any
any
Type.NonNullable(type any)
type anynonnull
type nullable none
type null
Type.NonNullable(type null)
type none
type nullable nullable T
type nullable T
Type.NonNullable(Type.NonNullable(type T))
Type.NonNullable(type T)
Type.NonNullable(type nullable T)
Type.NonNullable(type T)
type nullable (Type.NonNullable(type T))
type nullable T
En verdis tilskrevne type er typen som en verdi deklareres for å samsvare.
En verdi kan tilskrives en type ved hjelp av bibliotekfunksjonen Value.ReplaceType
. Denne funksjonen returnerer enten en ny verdi med typen som er tilskrevet, eller det oppstår en feil hvis den nye typen ikke er kompatibel med verdien.
Når en verdi er tilskrevet en type, forekommer bare en begrenset samsvarskontroll:
- Typen som er tilskrevet, må være ikke-abstrakt, ikke-nullbar og kompatibel med verdiens innebygde (opprinnelige) primitive type.
- Når en egendefinert type som definerer struktur er tilskrevet, må den samsvare med strukturen til verdien.
- For poster: Typen må lukkes, må definere samme antall felt som verdien, og må ikke inneholde valgfrie felt. (Typens feltnavn og felttyper erstatter de som for øyeblikket er knyttet til posten. Eksisterende feltverdier kontrolleres imidlertid ikke mot de nye felttypene.)
- For tabeller må typen definere samme antall kolonner som verdien. (Typens kolonnenavn og kolonnetyper erstatter de som for øyeblikket er knyttet til tabellen. Eksisterende kolonneverdier kontrolleres imidlertid ikke mot de nye kolonnetypene.)
- For funksjoner: Typen må definere samme antall obligatoriske parametere, i tillegg til samme antall valgfrie parametere, som verdien. (Typens parameter- og returdeklarasjoner, i tillegg til parameternavnene, erstatter de som er knyttet til funksjonsverdiens gjeldende type. De nye deklarasjonene vil imidlertid ikke ha noen innvirkning på funksjonens faktiske virkemåte.)
- For lister: Verdien må være en liste. (Eksisterende listeelementer kontrolleres imidlertid ikke mot den nye elementtypen.)
Bibliotekfunksjoner kan velge å beregne og tilskrive komplekse typer til resultater basert på de tilskrevne typene av inndataverdiene.
Den tilskrevne typen verdi kan hentes ved hjelp av bibliotekfunksjonen Value.Type
. Eksempel:
Value.Type( Value.ReplaceType( {1}, type {number} )
// type {number}
Typeekvivalens er ikke definert i M. En M-implementering kan eventuelt velge å bruke sine egne regler til å utføre likhetssammenligninger mellom typeverdier. Sammenligning av to typeverdier for likhet bør evalueres til true
hvis de anses som identiske av implementeringen, og false
ellers. I begge tilfeller må svaret som returneres, være konsekvent hvis de samme to verdiene gjentatte ganger sammenlignes. Vær oppmerksom på at i en gitt implementering kan sammenligning av identiske typeverdier (for eksempel (type text) = (type text)
) returnere true
, mens sammenligning av andre (for eksempel (type [a = text]) = (type [a = text])
) kanskje ikke er det.
Kompatibilitet mellom en gitt type og en primitiv type som kan nullstilles, kan bestemmes ved hjelp av bibliotekfunksjonen Type.Is
, som godtar en vilkårlig typeverdi som den første og en nullverdi av primitiv type som det andre argumentet:
Type.Is(type text, type nullable text) // true
Type.Is(type nullable text, type text) // false
Type.Is(type number, type text) // false
Type.Is(type [a=any], type record) // true
Type.Is(type [a=any], type list) // false
Det finnes ingen støtte i M for å fastslå kompatibiliteten til en gitt type med en egendefinert type.
Standardbiblioteket inkluderer en samling funksjoner for å trekke ut de definerende egenskapene fra en egendefinert type, slik at spesifikke kompatibilitetstester kan implementeres som M-uttrykk. Nedenfor finner du noen eksempler. se spesifikasjonen for M-biblioteket for å få mer informasjon.
Type.ListItem( type {number} )
// type number
Type.NonNullable( type nullable text )
// type text
Type.RecordFields( type [A=text, B=time] )
// [ A = [Type = type text, Optional = false],
// B = [Type = type time, Optional = false] ]
Type.TableRow( type table [X=number, Y=date] )
// type [X = number, Y = date]
Type.FunctionParameters(
type function (x as number, optional y as text) as number)
// [ x = type number, y = type nullable text ]
Type.FunctionRequiredParameters(
type function (x as number, optional y as text) as number)
// 1
Type.FunctionReturn(
type function (x as number, optional y as text) as number)
// type number