Typer

En typeværdi er en værdi, der klassificerer andre værdier. En værdi, der er klassificeret af en type, siges at være i overensstemmelse med denne type. M-typesystemet består af følgende typer:

  • Primitive typer, som klassificerer primitive værdier (binary, date, datetime, durationdatetimezone, list, logical, null, number, record, text, , time) typeog også omfatter en række abstrakte typer (function, table, anyog anynonnullnone)

  • Posttyper, der klassificerer postværdier baseret på feltnavne og værdityper

  • Listetyper, der klassificerer lister ved hjælp af en basistype for et enkelt element

  • Funktionstyper, der klassificerer funktionsværdier baseret på typerne af deres parametre og returværdier

  • Tabeltyper, der klassificerer tabelværdier baseret på kolonnenavne, kolonnetyper og nøgler

  • Null-typer, der klassificerer værdien null ud over alle de værdier, der er klassificeret af en basistype

  • Typetyper, der klassificerer værdier, der er typer

Sættet af primitive typer omfatter typerne af primitive værdier og en række abstrakte typer, som er typer, der ikke entydigt klassificerer nogen værdier: function, table, anyanynonnull og none. Alle funktionsværdier er i overensstemmelse med den abstrakte type function, alle tabelværdier til den abstrakte type table, alle værdier til den abstrakte type any, alle ikke-null-værdier til den abstrakte type anynonnullog ingen værdier til den abstrakte type none. Et udtryk af typen none skal udløse en fejl eller ikke kunne afsluttes, da der ikke kan oprettes en værdi, der er i overensstemmelse med typen none. Bemærk, at de primitive typer function og table er abstrakte, fordi ingen funktion eller tabel er direkte af disse typer. De primitive typer record og list er ikke-abstrakte, fordi de repræsenterer en åben post uden definerede felter og en liste af typen nogen.

Alle typer, der ikke er medlemmer af det lukkede sæt af primitive typer plus deres modparter, der kan være null, kaldes samlet for brugerdefinerede typer. Brugerdefinerede typer kan skrives ved hjælp af :type-expression

type-expression:
      primary-expression

      typeprimary-type
Type:
      primary-expression
      primary-type
primary-type:
      primitiv type
      posttype
      listetype
      funktionstype
      tabeltype
      nullable-type
primitiv-type:
en af
      any anynonnull binary date datetime datetimezone duration function list logical
      none null number record table text time type

Navne på primitive typer er kontekstafhængige nøgleord, der kun genkendes i en typekontekst . Brugen af parenteser i en typekontekst flytter grammatikken tilbage til en regulær udtrykskontekst, hvilket kræver brug af typenøgleordet for at flytte tilbage til en typekontekst. Hvis du f.eks. vil aktivere en funktion i en typekontekst , kan parenteser bruges:

type nullable ( Type.ForList({type number}) )   
// type nullable {number}

Parenteser kan også bruges til at få adgang til en variabel, hvis navn kolliderer med et navn af primitiv type :

let  record = type [ A = any ]  in  type {(record)} 
// type {[ A = any ]}

I følgende eksempel defineres en type, der klassificerer en liste over tal:

type { number }

På samme måde definerer følgende eksempel en brugerdefineret type, der klassificerer poster med obligatoriske felter med navnet X , og Y hvis værdier er tal:

type [ X = number, Y = number ]

Den tilskrevne type af en værdi hentes ved hjælp af standardbiblioteksfunktionen 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 bruges til at bestemme, om en værdis type er kompatibel med en given type, som vist i følgende eksempler:

1 is number          // true 
1 is text            // false 
{2} is list          // true

Operatoren as kontrollerer, om værdien er kompatibel med den angivne type, og udløser en fejl, hvis den ikke er. Ellers returneres den oprindelige værdi.

Value.Type( 1 as number )   // type number 
{2} as text                 // error, type mismatch

Bemærk, at operatorerne is og as kun accepterer primitive typer, der kan være null, som deres rette operand. M giver ikke mulighed for at kontrollere værdier for overensstemmelse med brugerdefinerede typer.

En type X er kompatibel med en type Y , hvis og kun hvis alle værdier, der er i overensstemmelse med X , også er i overensstemmelse med Y. Alle typer er kompatible med typen any , og ingen typer (men none sig selv) er kompatible med typen none. I følgende graf vises kompatibilitetsrelationen. Typekompatibilitet er refleksiv og transitiv. Det danner et gitter med typen any øverst og skriv none som den nederste værdi.) Navnene på abstrakte typer angives med kursiv.

Typekompatibilitet

Følgende operatorer er defineret for typeværdier:

Operator Resultat
x = y Lig med
x <> y Ikke lig med
x ?? y Coalesce

Den oprindelige type af typeværdier er den indbyggede type type.

Primitive typer

Typer i M-sproget udgør et usammenhængende hierarki med rod i typen any, som er den type, der klassificerer alle værdier. Alle M-værdier er i overensstemmelse med præcis én primitiv undertype af any. Det lukkede sæt af primitive typer, der er afledt af typen any , er som følger:

  • type null, som klassificerer null-værdien.
  • type logical, som klassificerer værdierne true og false.
  • type number, som klassificerer talværdier.
  • type time, som klassificerer klokkeslætsværdier.
  • type date, som klassificerer datoværdier.
  • type datetime, som klassificerer datetime-værdier.
  • type datetimezone, som klassificerer datetimezone-værdier.
  • type duration, som klassificerer varighedsværdier.
  • type text, som klassificerer tekstværdier.
  • type binary, som klassificerer binære værdier.
  • type type, som klassificerer typeværdier.
  • type list, som klassificerer listeværdier.
  • type record, som klassificerer postværdier.
  • type table, som klassificerer tabelværdier.
  • type function, som klassificerer funktionsværdier.
  • type anynonnull, som klassificerer alle værdier, der udelader null.
  • type none, som klassificerer ingen værdier.

Enhver type

Typen any er abstrakt, klassificerer alle værdier i M, og alle typer i M er kompatible med any. Variabler af typen any kan bindes til alle mulige værdier. Da any er abstrakt, kan den ikke tilskrives værdier, dvs. ingen værdi er direkte af typen any.

Listetyper

Alle værdier, der er en liste, er i overensstemmelse med den indbyggede type list, som ikke angiver nogen begrænsninger for elementerne i en listeværdi.

listetype:
      {elementtype}
item-type:
      Type

Resultatet af evalueringen af en listetype er en listetypeværdi , hvis basistype er list.

I følgende eksempler illustreres syntaksen for erklæring af homogene listetyper:

type { number }        // list of numbers type 
     { record }        // list of records type
     {{ text }}        // list of lists of text values

En værdi er i overensstemmelse med en listetype, hvis værdien er en liste, og hvert element i den pågældende listeværdi stemmer overens med listetypens elementtype.

Elementtypen for en listetype angiver en bundet: Alle elementer på en liste, der stemmer overens, er i overensstemmelse med elementtypen.

Posttyper

Alle værdier, der er en post, er i overensstemmelse med den indbyggede typepost, som ikke indeholder nogen begrænsninger for feltnavnene eller værdierne i en postværdi. En posttypeværdi bruges til at begrænse sættet af gyldige navne samt de typer værdier, der må knyttes til disse navne.

record-type:
      [open-record-marker]
      [field-specification-listopt]
      [field-specification-list , open-record-marker]
field-specification-list:
      field-specification
      field-specification,field-specification-list
field-specification:

      optionalopt field-name field-type-specificationopt
field-type-specification:

      =felttype
field-type:
      type
open-record-marker:

      ...

Resultatet af evalueringen af en posttype er en typeværdi, hvis basistype er record.

Følgende eksempler illustrerer syntaksen for erklæring af posttyper:

type [ X = number, Y = number] 
type [ Name = text, Age = number ]
type [ Title = text, optional Description = text ] 
type [ Name = text, ... ]

Posttyper lukkes som standard, hvilket betyder, at yderligere felter, der ikke findes på feltspecifikationslisten, ikke må være til stede i overensstemmende værdier. Hvis du medtager openrecord-marker i posttypen, erklæres typen åben, hvilket tillader felter, der ikke findes på listen med feltspecifikationer. Følgende to udtryk svarer til hinanden:

type record   // primitive type classifying all records 
type [ ... ]  // custom type classifying all records

En værdi er i overensstemmelse med en posttype, hvis værdien er en post, og hver feltspecifikation i posttypen er opfyldt. En feltspecifikation er opfyldt, hvis et af følgende er sandt:

  • Der findes et feltnavn, der svarer til specifikationens id, i posten, og den tilknyttede værdi er i overensstemmelse med specifikationens type

  • Specifikationen er markeret som valgfri, og der blev ikke fundet et tilsvarende feltnavn i posten

En overensstemmende værdi kan indeholde feltnavne, der ikke er angivet på listen med feltspecifikationer, hvis og kun hvis posttypen er åben.

Funktionstyper

Alle funktionsværdier er i overensstemmelse med den primitive type function, som ikke angiver nogen begrænsninger for typerne af funktionens formelle parametre eller funktionens returværdi. En brugerdefineret funktionstypeværdi bruges til at angive typebegrænsninger for signaturer for overensstemmende funktionsværdier.

function-type:
      function (parameter-specification-listopt)function-return-type
parameter-specification-list:
      required-parameter-specification-list
      required-parameter-specification-list
,optional-parameter-specification-list
      optional-parameter-specification-list
required-parameter-specification-list:
      required-parameter-specification
      required-parameter-specification
,required-parameter-specification-list
required-parameter-specification:
      parameterspecifikation
optional-parameter-specification-list:
      optional-parameter-specification
      optional-parameter-specification
,optional-parameter-specification-list
optional-parameter-specification:

      optionalparameterspecifikation
parameter-specification:
      parameter-name parameter-type
function-return-type:
      assertion
Påstand:

      asnullable-primitive-type

Resultatet af evalueringen af en funktionstype er en typeværdi, hvis basistype er function.

I følgende eksempler illustreres syntaksen for erklæring af funktionstyper:

type function (x as text) as number 
type function (y as number, optional z as text) as any

En funktionsværdi er i overensstemmelse med en funktionstype, hvis funktionsværdiens returtype er kompatibel med funktionstypens returtype, og hver parameterspecifikation for funktionstypen er kompatibel med den positionsmæssigt tilsvarende formelle parameter for funktionen. En parameterspecifikation er kompatibel med en formel parameter, hvis den angivne parametertypetype er kompatibel med typen af den formelle parameter, og parameterspecifikationen er valgfri, hvis den formelle parameter er valgfri.

Formelle parameternavne ignoreres med henblik på at bestemme funktionstypeoverensstemmelse.

Hvis du angiver en parameter som valgfrit, kan typen være null. Følgende opretter identiske funktionstyper:

type function (optional x as text) as any
type function (optional x as nullable text) as any

Tabeltyper

En tabeltypeværdi bruges til at definere strukturen af en tabelværdi.

table-type:
      tablerækketype
row-type:

      [field-specification-listopt]

Resultatet af evalueringen af en tabeltype er en typeværdi, hvis basistype er table.

Rækketypen for en tabel angiver kolonnenavnene og kolonnetyperne i tabellen som en lukket posttype. Så alle tabelværdier er i overensstemmelse med typen table, er rækketypen type record (den tomme åbne posttype). Typetabellen er derfor abstrakt, da ingen tabelværdi kan have typens tablerækketype (men alle tabelværdier har en rækketype, der er kompatibel med typen table's rækketype). I følgende eksempel vises oprettelsen af en tabeltype:

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 tabeltypeværdi indeholder også definitionen af en tabelværdis nøgler. En nøgle er et sæt kolonnenavne. Der kan højst angives én nøgle som tabellens primære nøgle. (I M har tabelnøgler ingen semantisk betydning. Det er dog almindeligt, at eksterne datakilder, f.eks. databaser eller OData-feeds, definerer nøgler over tabeller. Power Query bruger vigtige oplysninger til at forbedre ydeevnen af avancerede funktioner, f.eks. joinhandlinger på tværs af kilder.)

Standardbiblioteksfunktionerne Type.TableKeys, Type.AddTableKeyog Type.ReplaceTableKeys kan bruges til at hente nøglerne til en tabeltype, føje en nøgle til en tabeltype og erstatte alle nøgler af en tabeltype.

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

Typer, der kan være null

For alle type Tkan en variant, der kan være null, afledes ved hjælp af null-type:

nullable-type:
      nullabletype

Resultatet er en abstrakt type, der tillader værdier af typen T eller værdien null.

42 is nullable number             // true null is
nullable number                   // true

Ascription af type nullableT reduceres til ascription af type null eller typeT. Husk, at null-typer er abstrakte, og at ingen værdi kan være direkte af abstrakt type.

Value.Type(42 as nullable number)       // type number
Value.Type(null as nullable number)     // type null

Standardbiblioteksfunktionerne Type.IsNullable og Type.NonNullable kan bruges til at teste en type for nullability og til at fjerne nullability fra en type.

Følgende venteposition (for enhver type T):

  • type T er kompatibel med type nullable T
  • Type.NonNullable(type T) er kompatibel med type T

Følgende svarer parvis (for enhver 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

Tilskrevet type af en værdi

En værdis tilskrevne type er den type, som en værdi erklæresfor at være i overensstemmelse med.

En værdi kan tilskrives en type ved hjælp af biblioteksfunktionen Value.ReplaceType. Denne funktion returnerer enten en ny værdi med den tilskrevne type eller udløser en fejl, hvis den nye type ikke er kompatibel med værdien.

Når en værdi tilskrives en type, sker der kun en begrænset overensstemmelseskontrol:

  • Den type, der tilskrives, skal være ikke-abstrakt, ikke-null og kompatibel med værdiens indbyggede (oprindelige) primitive type.
  • Når en brugerdefineret type, der definerer strukturen, tilskrives, skal den matche strukturen af værdien.
    • For poster: Typen skal lukkes, skal definere det samme antal felter som værdien og må ikke indeholde valgfrie felter. (Feltnavnene og felttyperne for typen erstatter dem, der i øjeblikket er knyttet til posten. Eksisterende feltværdier kontrolleres dog ikke i forhold til de nye felttyper.)
    • For tabeller: Typen skal definere det samme antal kolonner som værdien. (Kolonnenavnene og kolonnetyperne for typen erstatter dem, der i øjeblikket er knyttet til tabellen. Eksisterende kolonneværdier kontrolleres dog ikke i forhold til de nye kolonnetyper.)
    • For funktioner: Typen skal definere det samme antal påkrævede parametre samt det samme antal valgfrie parametre som værdien. (Typens parameter og returantagelser samt dens parameternavne erstatter dem, der er knyttet til funktionsværdiens aktuelle type. De nye antagelser har dog ingen indvirkning på funktionens faktiske funktionsmåde.)
    • For lister: Værdien skal være en liste. Eksisterende listeelementer kontrolleres dog ikke i forhold til den nye elementtype.

Biblioteksfunktioner kan vælge at beregne og tilskrive komplekse typer til resultater baseret på de tilskrevne typer af inputværdier.

Den tilskrevne type af en værdi kan hentes ved hjælp af biblioteksfunktionen Value.Type. Eksempler:

Value.Type( Value.ReplaceType( {1}, type {number} ) 
// type {number}

Typeækvivalens og kompatibilitet

Typeækvivalens er ikke defineret i M. En M-implementering kan eventuelt vælge at bruge sine egne regler til at udføre lighedssammenligninger mellem typeværdier. Hvis du sammenligner to typeværdier for lighed, skal det evalueres til , hvis de anses for at true være identiske af implementeringen, og false ellers. I begge tilfælde skal det returnerede svar være konsistent, hvis de samme to værdier sammenlignes gentagne gange. Bemærk, at hvis du sammenligner nogle identiske typeværdier (f.eks. (type text) = (type text)) i en given implementering, returneres true, mens andre (f.eks (type [a = text]) = (type [a = text]). ) muligvis ikke sammenlignes.

Kompatibilitet mellem en given type og en primitiv type, der kan være null, kan bestemmes ved hjælp af biblioteksfunktionen Type.Is, som accepterer en vilkårlig typeværdi som den første og en primitiv typeværdi, der kan være null, som det andet argument:

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

Der er ingen understøttelse i M for at bestemme kompatibiliteten af en given type med en brugerdefineret type.

Standardbiblioteket indeholder en samling funktioner, der udtrækker de definerende egenskaber fra en brugerdefineret type, så specifikke kompatibilitetstest kan implementeres som M-udtryk. Nedenfor er nogle eksempler. se specifikationen for M-biblioteket for at få flere oplysninger.

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