Läs på engelska

Dela via


Typer

Ett typvärde är ett värde som klassificerar andra värden. Ett värde som klassificeras av en typ sägs överensstämma med den typen. M-typsystemet består av följande typer:

  • Primitiva typer, som klassificerar primitiva värden (binary, , datetimedate, datetimezone, duration, list, logical, null, number, record, text, , time) typeoch även innehåller ett antal abstrakta typer (function, table, anyoch anynonnull none)

  • Posttyper, som klassificerar postvärden baserat på fältnamn och värdetyper

  • Listtyper, som klassificerar listor med en bastyp för ett objekt

  • Funktionstyper som klassificerar funktionsvärden baserat på typerna av deras parametrar och returnerar värden

  • Tabelltyper som klassificerar tabellvärden baserat på kolumnnamn, kolumntyper och nycklar

  • Nullbara typer, som klassificerar värdet null utöver alla värden som klassificeras av en bastyp

  • Typtyper som klassificerar värden som är typer

Uppsättningen primitiva typer innehåller typerna av primitiva värden och ett antal abstrakta typer, som är typer som inte unikt klassificerar några värden: function, table, anyanynonnull och none. Alla funktionsvärden överensstämmer med den abstrakta typen function, alla tabellvärden till den abstrakta typen table, alla värden till den abstrakta typen any, alla icke-null-värden till den abstrakta typen anynonnulloch inga värden till den abstrakta typen none. Ett uttryck av typen none måste generera ett fel eller avslutas inte eftersom inget värde kunde skapas som överensstämmer med typen none. Observera att de primitiva typerna function och table är abstrakta eftersom ingen funktion eller tabell är direkt av dessa typer. De primitiva typerna record och list är icke-abstrakta eftersom de representerar en öppen post utan definierade fält respektive en lista av typen någon.

Alla typer som inte är medlemmar i den stängda uppsättningen primitiva typer plus deras nullbara motsvarigheter kallas gemensamt anpassade typer. Anpassade typer kan skrivas med hjälp av :type-expression

type-expression:
      primary-expression

      typeprimär typ
typ:
      primary-expression
      primär typ
primär typ:
      primitiv typ
      posttyp
      listtyp
      funktionstyp
      tabelltyp
      nullable-type
primitiv-typ:
en av
      any anynonnull binary date datetime datetimezone duration function list logical
      none null number record table text time type

Namn av primitiv typ är kontextuella nyckelord som endast identifieras i en typkontext . Användningen av parenteser i en typkontext flyttar grammatiken tillbaka till en kontext för reguljära uttryck, vilket kräver att nyckelordet av typen används för att gå tillbaka till en typkontext. Om du till exempel vill anropa en funktion i en typkontext kan parenteser användas:

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

Parenteser kan också användas för att komma åt en variabel vars namn kolliderar med ett primitivt namn :

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

I följande exempel definieras en typ som klassificerar en lista med tal:

type { number }

På samma sätt definierar följande exempel en anpassad typ som klassificerar poster med obligatoriska fält med namnet X och Y vars värden är tal:

type [ X = number, Y = number ]

Den angivna typen av ett värde hämtas med hjälp av standardbiblioteksfunktionen Value.Type, som du ser i följande exempel:

Value.Type( 2 )                 // type number 
Value.Type( {2} )               // type list 
Value.Type( [ X = 1, Y = 2 ] )  // type record

Operatorn is används för att avgöra om ett värdes typ är kompatibel med en viss typ, enligt följande exempel:

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

Operatorn as kontrollerar om värdet är kompatibelt med den angivna typen och genererar ett fel om det inte är det. Annars returneras det ursprungliga värdet.

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

Observera att operatorerna is och as endast accepterar nullbara primitiva typer som sin rätta operande. M tillhandahåller inte sätt att kontrollera värden för överensstämmelse med anpassade typer.

En typ X är kompatibel med en typ Y om och endast om alla värden som överensstämmer med också överensstämmer X med Y. Alla typer är kompatibla med typen any och inga typer (men none själva) är kompatibla med typen none. Följande diagram visar kompatibilitetsrelationen. (Typkompatibiliteten är reflexiv och transitiv. Den bildar ett gitter med typen any som överkant och skriver none som det nedre värdet.) Namnen på abstrakta typer anges i kursiv stil.

Typkompatibilitet

Följande operatorer definieras för typvärden:

Operator Result
x = y Equal
x <> y Not equal
x ?? y Coalesce

Den interna typen av typvärden är den inbyggda typen type.

Primitiva typer

Typer i M-språket utgör en uppdelad hierarki rotad vid typen any, vilket är den typ som klassificerar alla värden. Alla M-värden överensstämmer med exakt en primitiv undertyp av any. Den stängda uppsättningen primitiva typer som härleds från typen any är följande:

  • type null, som klassificerar null-värdet.
  • type logical, som klassificerar värdena true och false.
  • type number, som klassificerar talvärden.
  • type time, som klassificerar tidsvärden.
  • type date, som klassificerar datumvärden.
  • type datetime, som klassificerar datetime-värden.
  • type datetimezone, som klassificerar datetimezone-värden.
  • type duration, som klassificerar varaktighetsvärden.
  • type text, som klassificerar textvärden.
  • type binary, som klassificerar binära värden.
  • type type, som klassificerar typvärden.
  • type list, som klassificerar listvärden.
  • type record, som klassificerar postvärden.
  • type table, som klassificerar tabellvärden.
  • type function, som klassificerar funktionsvärden.
  • type anynonnull, som klassificerar alla värden exklusive null.
  • type none, som inte klassificerar några värden.

Valfri typ

Typen any är abstrakt, klassificerar alla värden i M och alla typer i M är kompatibla med any. Variabler av typen any kan bindas till alla möjliga värden. Eftersom any är abstrakt kan det inte tillskrivas värden, det vill säga inget värde är direkt av typen any.

Listtyper

Alla värden som är en lista överensstämmer med den inbyggda typen list, som inte begränsar objekten i ett listvärde.

listtyp:
      { objekttyp }
objekttyp:
      typ

Resultatet av utvärderingen av en listtyp är ett listtypsvärde vars bastyp är list.

Följande exempel illustrerar syntaxen för att deklarera homogena listtyper:

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

Ett värde överensstämmer med en listtyp om värdet är en lista och varje objekt i listvärdet överensstämmer med listtypens objekttyp.

Objekttypen för en listtyp anger en bindning: alla objekt i en överensstämmande lista överensstämmer med objekttypen.

Posttyper

Alla värden som är en post överensstämmer med den inbyggda typposten, vilket inte begränsar fältnamnen eller värdena i ett postvärde. Ett värde av posttyp används för att begränsa uppsättningen med giltiga namn samt de typer av värden som tillåts associeras med dessa namn.

posttyp:
      [open-record-marker ]
      [ field-specification-listopt ]
      [ field-specification-list , open-record-marker ]
field-specification-list:
      fältspecifikation
      field-specification , field-specification-list
fältspecifikation:

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

      =fälttyp
field-type:
      type
open-record-marker:

      ...

Resultatet av utvärderingen av en posttyp är ett typvärde vars bastyp är record.

Följande exempel illustrerar syntaxen för att deklarera posttyper:

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

Posttyper stängs som standard, vilket innebär att ytterligare fält som inte finns i fältpecifieringslistan inte tillåts finnas i överensstämmande värden. Om du inkluderar openrecord-markören i posttypen deklareras typen som öppen, vilket tillåter fält som inte finns i fältspecifikationslistan. Följande två uttryck är likvärdiga:

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

Ett värde överensstämmer med en posttyp om värdet är en post och varje fältspecifikation i posttypen är uppfylld. En fältspecifikation uppfylls om något av följande är sant:

  • Ett fältnamn som matchar specifikationens identifierare finns i posten och det associerade värdet överensstämmer med specifikationens typ

  • Specifikationen är markerad som valfri och inget motsvarande fältnamn finns i posten

Ett överensstämmande värde kan innehålla fältnamn som inte anges i fältspecifikationslistan om och endast om posttypen är öppen.

Funktionstyper

Alla funktionsvärden överensstämmer med den primitiva typen function, som inte begränsar typen av funktionens formella parametrar eller funktionens returvärde. Ett anpassat värde av funktionstyp används för att placera typbegränsningar på signaturerna för överensstämmande funktionsvärden.

funktionstyp:
      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
parameterspecifikation:
      parameter-name parameter-type
function-return-type:
      assertion
påstående:

      as nullable-primitive-type

Resultatet av utvärderingen av en funktionstyp är ett typvärde vars bastyp är function.

Följande exempel illustrerar syntaxen för att deklarera funktionstyper:

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

Ett funktionsvärde överensstämmer med en funktionstyp om returtypen för funktionsvärdet är kompatibel med funktionstypens returtyp och varje parameterspecifikation för funktionstypen är kompatibel med den positionellt motsvarande formella parametern för funktionen. En parameterspecifikation är kompatibel med en formell parameter om den angivna parametertypen är kompatibel med typen av den formella parametern och parameterspecifikationen är valfri om den formella parametern är valfri.

Formella parameternamn ignoreras för att fastställa funktionstypsefterlevnad.

Om du anger en parameter som valfritt implicit kan dess typ vara null. Följande skapar identiska funktionstyper:

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

Tabelltyper

Ett tabelltypsvärde används för att definiera strukturen för ett tabellvärde.

tabelltyp:
      tableradtyp
radtyp:

      [ field-specification-listopt ]

Resultatet av utvärderingen av en tabelltyp är ett typvärde vars bastyp är table.

Radtypen för en tabell anger kolumnnamnen och kolumntyperna i tabellen som en stängd posttyp. Så att alla tabellvärden överensstämmer med typen tableär dess radtyp typ record (den tomma öppna posttypen). Därför är typtabellen abstrakt eftersom inget tabellvärde kan ha typens tableradtyp (men alla tabellvärden har en radtyp som är kompatibel med typen tableradtyp). I följande exempel visas konstruktionen av en tabelltyp:

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

Ett tabelltypsvärde innehåller också definitionen av ett tabellvärdes nycklar. En nyckel är en uppsättning kolumnnamn. Högst en nyckel kan anges som tabellens primära nyckel. (I M har tabellnycklar ingen semantisk betydelse. Det är dock vanligt att externa datakällor, till exempel databaser eller OData-feeds, definierar nycklar över tabeller. Power Query använder viktig information för att förbättra prestanda för avancerade funktioner, till exempel anslutningsåtgärder mellan källor.)

Standardbiblioteksfunktionerna Type.TableKeys, Type.AddTableKeyoch Type.ReplaceTableKeys kan användas för att hämta nycklarna för en tabelltyp, lägga till en nyckel i en tabelltyp och ersätta alla nycklar av en tabelltyp.

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 som kan ogiltigas

För alla type Tkan en nullbar variant härledas med hjälp av nullable-type:

nullable-type:
      nullabletyp

Resultatet är en abstrakt typ som tillåter värden av typen T eller värdet null.

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

Ascription av type nullable T reducerar till ascription av type null eller type T. (Kom ihåg att nullbara typer är abstrakta och att inget värde kan vara direkt av abstrakt typ.)

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

Standardbiblioteksfunktionerna Type.IsNullable och Type.NonNullable kan användas för att testa en typ för nullbarhet och för att ta bort nullbarhet från en typ.

Följande undantag (för alla type T):

  • type T är kompatibel med type nullable T
  • Type.NonNullable(type T) är kompatibel med type T

Följande är parvis likvärdiga (för alla 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

Tillskriven typ av ett värde

Ett värdes tillskrivna typ är den typ som ett värde deklareras överensstämma med.

Ett värde kan tillskrivas en typ med hjälp av biblioteksfunktionen Value.ReplaceType. Den här funktionen returnerar antingen ett nytt värde med typen tillskriven eller genererar ett fel om den nya typen inte är kompatibel med värdet.

När ett värde tilldelas en typ sker endast en begränsad efterlevnadskontroll:

  • Den typ som tillskrivas måste vara icke-abstrakt, icke-nullbar och kompatibel med värdets inbyggda (interna) primitiva typ.
  • När en anpassad typ som definierar struktur tillskrivas måste den matcha värdets struktur.
    • För poster: Typen måste stängas, måste definiera samma antal fält som värdet och får inte innehålla några valfria fält. (Typens fältnamn och fälttyper ersätter de som för närvarande är associerade med posten. Befintliga fältvärden kontrolleras dock inte mot de nya fälttyperna.)
    • För tabeller: Typen måste definiera samma antal kolumner som värdet. (Typens kolumnnamn och kolumntyper ersätter de som för närvarande är associerade med tabellen. Befintliga kolumnvärden kontrolleras dock inte mot de nya kolumntyperna.)
    • För funktioner: Typen måste definiera samma antal obligatoriska parametrar samt samma antal valfria parametrar som värdet. (Typens parameter och returkontroller, samt dess parameternamn, ersätter de som är associerade med funktionsvärdets aktuella typ. De nya försäkran påverkar dock inte funktionens faktiska beteende.)
    • För listor: Värdet måste vara en lista. (Befintliga listobjekt kontrolleras dock inte mot den nya objekttypen.)

Biblioteksfunktioner kan välja att beräkna och tillskriva komplexa typer till resultat baserat på de tillskrivna typerna av indatavärden.

Den angivna typen av ett värde kan hämtas med hjälp av biblioteksfunktionen Value.Type. Till exempel:

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

Typ av likvärdighet och kompatibilitet

Typjämvikt definieras inte i M. En M-implementering kan välja att använda sina egna regler för att utföra likhetsjämförelser mellan typvärden. Jämförelse av två typvärden för likhet bör utvärderas till true om de anses vara identiska med implementeringen, och false i annat fall. I båda fallen måste svaret som returneras vara konsekvent om samma två värden jämförs upprepade gånger. Observera att om du jämför vissa identiska typvärden (till exempel (type text) = (type text)) inom en viss implementering kan det hända trueatt andra (till exempel (type [a = text]) = (type [a = text])) inte jämförs.

Kompatibilitet mellan en viss typ och en nullbar primitiv typ kan fastställas med hjälp av biblioteksfunktionen Type.Is, som accepterar ett godtyckligt typvärde som det första och ett nullbart primitivt typvärde som sitt andra 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

Det finns inget stöd i M för att fastställa kompatibiliteten för en viss typ med en anpassad typ.

Standardbiblioteket innehåller en samling funktioner för att extrahera de definierande egenskaperna från en anpassad typ, så specifika kompatibilitetstester kan implementeras som M-uttryck. Nedan visas några exempel. Se M-biblioteksspecifikationen för fullständig information.

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