共用方式為


Values

值是透過計算表達式所產生的資料。 本節描述 M 語言中值的種類。 每種值類型都對應一個字面語法、一組屬於該類型的值、一組在該值集合上定義的運算子,以及賦予新建值的內在型態。

種類 Literal
Null null
Logical true    false
Number 0    1    -1    1.5    2.3e-5
Time #time(09,15,00)
Date #date(2013,02,26)
DateTime #datetime(2013,02,26, 09,15,00)
DateTimeZone #datetimezone(2013,02,26, 09,15,00, 09,00)
Duration #duration(0,1,30,0)
Text "hello"
Binary #binary("AQID")
List {1, 2, 3}
Record [ A = 1, B = 2 ]
Table #table({"X","Y"},{{0,1},{1,0}})
Function (x) => x + 1
Type type { number }    type table [ A = any, B = text ]

以下章節將詳細介紹每種價值類型。 型別與型別歸屬在 「型別」中正式定義。 函數值定義於 函數中。 以下章節列出每種值類型定義的運算子並舉例說明。 運算子語意的完整定義詳見 《運算子》一文

Null

空值用來表示值的缺失,或是狀態不確定或未知的值。 空值則使用文字 null。 以下運算子定義為零值:

Operator Result
x > y 大於
x >= y 大於或等
x < y 小於
x <= y 小於或等於
x = y Equal
x <> y 不相等
x ?? y Coalesce

該值的 null 本體型態為內在型態 null

Logical

對於布林運算,邏輯 為真或假。 一個邏輯值是利用文字 truefalse來寫的。 以下運算子定義為邏輯值:

Operator Result
x > y 大於
x >= y 大於或等
x < y 小於
x <= y 小於或等於
x = y Equal
x <> y 不相等
x or y 條件邏輯或
x ?? y Coalesce
x and y 條件邏輯 AND
not x 邏輯上不是

邏輯值(truefalse)的原生型態即為內在型態 logical

Number

值用於數 值與算術運算。 以下是數值的範例:

3.14  // Fractional number 
-1.5  // Fractional number 
1.0e3 // Fractional number with exponent
123   // Whole number 
1e3   // Whole number with exponent 
0xff  // Whole number in hex (255)

數字的表示精度至少與 Double 相當(但可能保留更高精度)。 雙重表示法與 IEEE 64 位元雙精度二元浮點運算標準一致,該標準見於 [IEEE 754-2008]。 ( 雙重 表示法的動態範圍約為 5.0 x 10324 至 1.7 x 10308 ,精度為 15-16 位數。)

以下特殊值也被視為 數字 值:

  • 正零和負零。 在大多數情況下,正零與負零的行為與簡單值零相同,但 某些運算會區分兩者

  • 正無限大(#infinity)與負無限大(-#infinity)。 無窮大是通過將非零數除以零等運算產生的。 例如,會 1.0 / 0.0 得到正無限大,而 -1.0 / 0.0 則會產生負無限大。

  • 非數字值(#nan),常縮寫為 NaN。 NaN 是由無效的浮點運算所產生,例如將零除以零。

二元數學運算使用 Precision。 精度決定運算元四捨五入的定義域及操作執行的定義域。 在沒有明確指定的精度的情況下,這類運算會使用 雙倍精度來執行。

  • 如果數學運算的結果對目標格式來說太小,該運算的結果將變成正零或負零。

  • 若數學運算結果對目標格式來說過大,該運算結果將變成正無限大或負無限大。

  • 若數學運算無效,該運算結果即為 NaN。

  • 如果浮點運算的一或兩個運算元是 NaN,則運算的結果會變成 NaN。

以下運算子定義於數值:

Operator Result
x > y 大於
x >= y 大於或等
x < y 小於
x <= y 小於或等於
x = y Equal
x <> y 不相等
x + y Sum
x - y Difference
x * y Product
x / y Quotient
x ?? y Coalesce
+x 一元正號
-x Negation

數字值的原生類型為內在類型 number

Time

時間值儲存一個不透明的一天中時間表示。 時間以 午夜以來的滴答數編碼,計算24小時制中經過的100奈秒滴答數。 自午夜以來最大滴答數對應於23:59:59.9999999小時。

雖然沒有時間的字面語法,但提供了數個標準函式庫函式來構造時間。 時間也可以用內在函數 #time構造:

#time(hour, minute, second)

以下條件必須成立,否則會產生帶有原因代碼 Expression.Error 的錯誤:

0 ≤ ≤ 24
0 ≤ ≤ 59
0 ≤秒 ≤ 59

此外,若時=24,則分秒必須為零。

以下運算子定義時間值:

Operator Result
x = y Equal
x <> y 不相等
x >= y 大於或等
x > y 大於
x < y 小於
x <= y 小於或等於
x ?? y Coalesce

以下運算子允許其一個或兩個運算元為日期:

Operator 左操作數 右運算數 Meaning
x + y time duration 日期依持續時間相抵
x + y duration time 日期依持續時間相抵
x - y time duration 日期抵消時長
x - y time time 日期間隔
x & y date time 合併日期時間

時間值的原生類型為內在型態 time

Date

日期值儲存特定日期的不透明表示。 日期以自紀元起的 數編碼,從公元公元1月1日開始。 自紀元以來的最大天數為3652058,對應於9999年12月31日。

雖然沒有日期的字面語法,但提供了幾個標準函式庫函式來構造日期。 日期也可以利用內在函數 #date構造:

#date(year, month, day)

以下條件必須成立,否則會產生帶有原因代碼 Expression.Error 的錯誤:

1 ≤年 ≤ 9999年
1 ≤月 ≤ 12
1 ≤ 31≤

此外,該日期必須對所選月份和年份有效。

以下運算子定義日期值:

Operator Result
x = y Equal
x <> y 不相等
x >= y 大於或等
x > y 大於
x < y 小於
x <= y 小於或等於
x ?? y Coalesce

以下運算子允許其一個或兩個運算元為日期:

Operator 左操作數 右運算數 Meaning
x + y date duration 日期依持續時間相抵
x + y duration date 日期依持續時間相抵
x - y date duration 日期抵消時長
x - y date date 日期間隔
x & y date time 合併日期時間

日期值的原生類型為內在型態 date

DateTime

datetime 值同時包含日期與時間。

雖然沒有字面上的日期時值語法,但提供了幾個標準函式庫函式來構建它們。 日期時間也可以用內在函數 #datetime構造:

#datetime(year, month, day, hour, minute, second)

以下必須保持或錯誤,且原因代碼為 Expression。錯誤被提出:1 ≤ 年 ≤ 9999
1 ≤月 ≤ 12
1 ≤ 31≤
0 ≤ ≤ 23
0 ≤ ≤ 59
0 ≤秒 ≤ 59

此外,該日期必須對所選月份和年份有效。

以下運算子定義為日期時間值:

Operator Result
x = y Equal
x <> y 不相等
x >= y 大於或等
x > y 大於
x < y 小於
x <= y 小於或等於
x ?? y Coalesce

以下運算子允許其一個或兩個運算元成為日期時間:

Operator 左操作數 右運算數 Meaning
x + y datetime duration 日期時間依持續時間偏移
x + y duration datetime 日期時間依持續時間偏移
x - y datetime duration Datetime 以消除時長抵消
x - y datetime datetime 日期間隔

datetime 值的原生類型為內在型態 datetime

DateTimeZone

DateTimezone 值包含一個 datetime 和一個時區。 時 與UTC偏移的分鐘數編碼,該時間 部分應與 世界協調時間(UTC)相差多少分鐘。 UTC的最小分鐘數偏移為-840分鐘,代表UTC偏移為-14:00,比UTC早十四小時。 UTC最大偏移分鐘數為840分鐘,對應14:00的UTC偏移。

雖然沒有明確的日期時區語法,但提供了幾個標準函式庫函式來構造它們。 日期時區也可以使用內在函數 #datetimezone構造:

#datetimezone(
       year, month, day,
       hour, minute, second,
       offset-hours, offset-minutes)

以下條件必須成立,否則會產生帶有原因代碼 Expression.Error 的錯誤:

1 ≤年 ≤ 9999年
1 ≤月 ≤ 12
1 ≤ 31≤
0 ≤ ≤ 23
0 ≤ ≤ 59
0 ≤秒 ≤ 59
-14小時≤≤14小時
-59分鐘≤偏移分鐘≤59分鐘

此外,該日期必須對所選月份和年份有效,若偏移時數 = 14,則偏移分鐘 <= 0;若偏移時數 = -14,則偏移分鐘 >= 0。

以下運算子定義了日期時區的值:

Operator Result
x = y Equal
x <> y 不相等
x >= y 大於或等
x > y 大於
x < y 小於
x <= y 小於或等於
x ?? y Coalesce

以下營運商允許其一個或兩個操作元為日期時區:

Operator 左操作數 右運算數 Meaning
x + y datetimezone duration Datetimezone 依持續時間偏移
x + y duration datetimezone Datetimezone 依持續時間偏移
x - y datetimezone duration Datetimezone以消去的時長抵消
x - y datetimezone datetimezone 日期時區間的持續時間

Datetimezone 值的原生類型為內在型態 datetimezone

Duration

持續時間值儲存一個不透明的表示,表示時間軸上兩點之間的距離,測量為100奈秒刻。 持續時間的大小可以是正的或負的,正值表示時間向前的進展,負值則表示時間向後的進展。 在一個 持續時間 內可儲存的最小值為 -9,223,372,036,854,775,808 tick,或倒推 10,675,199 天 2 小時 48 分 05.4775808 秒。 每次 持續 時間內最大可儲存的值為 9,223,372,036,854,775,807 tick,或是 10,675,199 天 2 小時 48 分 05.4775807 秒。

雖然沒有字面上的語法來描述時值,但提供了幾個標準函式庫函式來構造時值。 持續時間也可用內徵函 #duration數構造:

#duration(0, 0, 0, 5.5)          // 5.5 seconds 
#duration(0, 0, 0, -5.5)         // -5.5 seconds 
#duration(0, 0, 5, 30)           // 5.5 minutes 
#duration(0, 0, 5, -30)          // 4.5 minutes 
#duration(0, 24, 0, 0)           // 1 day 
#duration(1, 0, 0, 0)            // 1 day

以下運算子定義於持續時間值上:

Operator Result
x = y Equal
x <> y 不相等
x >= y 大於或等
x > y 大於
x < y 小於
x <= y 小於或等於
x ?? y Coalesce

此外,以下運算子允許其中一個或兩個運算元為持續時間值:

Operator 左操作數 右運算數 Meaning
x + y datetime duration 日期時間依持續時間偏移
x + y duration datetime 日期時間依持續時間偏移
x + y duration duration 持續時間總和
x - y datetime duration Datetime 以消除時長抵消
x - y datetime datetime 日期間隔
x - y duration duration 持續時間的差異
x * y duration number n 乘以持續時間
x * y number duration n 乘以持續時間
x / y duration number 持續時間的分數
x / y duration duration 持續時間的數值商

本來的持續時間類型為內在類型 duration

文字

文字值代表一串 Unicode 字元。 文字值的字面形式符合以下文法:

_text-literal:
       " 文字字元選擇"
文字字元:
      文字字元-字元-文字-字元-字元 opt
text-literal-character:
      single-text-character
      character-escape-sequence
      double-quote-escape-sequence
單文字字元:

      除了 "U+0022)或 #U+0023)外,任何字元後面跟 ( 著(U+0028
double-quote-escape-sequence:
       ""U+0022U+0022

以下是一個 文字 值的範例:

"ABC" // the text value ABC

以下運算子定義於 文字 值上:

Operator Result
x = y Equal
x <> y 不相等
x >= y 大於或等
x > y 大於
x < y 小於
x <= y 小於或等於
x & y Concatenation
x ?? y Coalesce

文本值的原生類型為內在類型 text

Binary

二進位值代表一串位元組。

雖然二進位值沒有字面上的語法,但提供了幾個標準函式庫函式來構造它們。 二元值也可用內徵函 #binary數 來構造。

以下範例從一個位元組清單中構造出二進位值:

#binary( {0x00, 0x01, 0x02, 0x03} )

以下運算子定義於 二進位 值:

Operator Result
x = y Equal
x <> y 不相等
x >= y 大於或等
x > y 大於
x < y 小於
x <= y 小於或等於
x ?? y Coalesce

二進位值的原生型態是內在型 二元值

List

列表值是指在列舉時產生一連串值的值。 由串列產生的值可以包含任何類型的值,包括一個串列。 列表可使用初始化語法構建,具體如下:

list-expression:
      { 項目清單選擇 }
項目清單:
      項目
      項目
,項目清單
item:
      運算式
      表達
..

以下是一個列表 表達 式的範例,定義了一個包含三個文字值的列表: "A"、、 "B""C"

{"A", "B", "C"}

"A" 是清單中的第一個項目,值 "C" 是列表中的最後一個項目。

  • 清單中的項目在被存取之前不會被評估。
  • 雖然使用清單語法建構的清單值會依照項目 列表中出現的順序產生項目,但一般而言,從函式庫函式回傳的列表每次列舉時可能會產生不同的集合或不同數量的值。

若要在列表中包含整數序列,可以使用以下 a..b 形式:

{ 1, 5..9, 11 }     // { 1, 5, 6, 7, 8, 9, 11 }

清單中的項目數量,稱為 清單數量,可以透過該 List.Count 函數來確定。

List.Count({true, false})  // 2 
List.Count({})             // 0

一個清單實際上可以包含無限數量的項目; List.Count 因為此類列表未定義,可能產生錯誤或不終止。

如果清單中沒有任何項目,則稱為 空清單。 空清單寫成:

{}  // empty list

以下運算子被定義用於列表:

Operator Result
x = y Equal
x <> y 不相等
x & y Concatenate
x ?? y Coalesce

例如:

{1, 2} & {3, 4, 5}   // {1, 2, 3, 4, 5} 
{1, 2} = {1, 2}      // true 
{2, 1} <> {1, 2}     // true

列表值的原生類型是內在型態 list,它指定了 的項目類型。any

Record

記錄值是一串有序的欄位序列。 欄位欄位名稱(欄位名稱)組成,該欄位是唯一識別記錄中欄位的文字值,以及欄位。 欄位值可以是任何類型的值,包括記錄值。 記錄可用初始化語法建構,具體如下:

record-expression:
       [ 場地列表OPT]
田野名單:
      欄位
      田野
,名錄
field:
      欄位名稱
=表達式
field-name:
      generalized-identifier
      引用識別碼

以下範例構造一個記錄,其欄位為 x1,值為 ,以及一個名為 y2的欄位。

[ x = 1, y = 2 ]

以下範例構造一個名為 a a 的欄位,且帶有巢狀記錄值。 巢狀記錄有一個名為 b 的欄位,值為 2

[ a = [ b = 2 ] ]

評估記錄表達式時,以下情況成立:

  • 每個欄位名稱所指派的表達式用來決定該欄位的值。

  • 如果賦值欄位名稱的表達式在評估時產生一個值,那麼該值就成為結果記錄欄位的值。

  • 若欄位名稱的表達式在評估時產生錯誤,則錯誤的事實會與欄位一同記錄,連同錯誤值一併記錄。 後續存取該欄位時,錯誤會以記錄值重新提出。

  • 在像父環境這樣的環境中,只有合併變數時才會評估,這些變數對應記錄中除初始化欄位外的所有欄位的值。

  • 記錄中的值在存取對應欄位後才會被評估。

  • 記錄中的一個值最多會被評估一次。

  • 該表達式的結果是一個帶有空元資料記錄的記錄值。

  • 記錄中欄位的順序由它們在 記錄初始化運算式中出現的順序決定。

  • 每個欄位名稱必須在紀錄中唯一,否則就是錯誤。 名稱是透過序數比較來比較的。

    [ x = 1, x = 2 ] // error: field names must be unique 
    [ X = 1, x = 2 ] // OK

沒有欄位的紀錄稱為 空記錄,寫作方式如下:

[] // empty record

雖然在存取欄位或比較兩筆記錄時,欄位的順序並不重要,但在其他情境中則很重要,例如當記錄欄位被列舉時。

當取得欄位時,這兩個紀錄會產生不同的結果:

Record.FieldNames([ x = 1, y = 2 ]) // [ "x", "y" ] 
Record.FieldNames([ y = 1, x = 2 ]) // [ "y", "x" ]

記錄中的欄位數量可以用函 Record.FieldCount 數來確定。 例如:

Record.FieldCount([ x = 1, y = 2 ])  // 2 
Record.FieldCount([])                // 0

除了使用記錄初始化語法 [ ]外,紀錄還可以由值清單、欄位名稱清單或紀錄類型來構造。 例如:

Record.FromList({1, 2}, {"a", "b"})

上述等價於:

[ a = 1, b = 2 ]

以下運算子定義為記錄值:

Operator Result
x = y Equal
x <> y 不相等
x & y Merge
x ?? y Coalesce

以下範例說明上述運算子。 請注意,記錄合併會使用右側運算元欄位來覆蓋左側運算元欄位,以防欄位名稱有重疊。

[ a = 1, b = 2 ] & [ c = 3 ]    // [ a = 1, b = 2, c = 3 ] 
[ a = 1, b = 2 ] & [ a = 3 ]    // [ a = 3, b = 2 ] 
[ a = 1, b = 2 ] = [ b = 2, a = 1 ]         // true 
[ a = 1, b = 2, c = 3 ] <> [ a = 1, b = 2 ] // true

記錄值的原生類型是內在型態 record,它指定了一個開放的空欄位清單。

Table

表值是一列有序的列。 是一串有序的欄位值序列。 資料表的類型決定了所有資料列的長度、資料表欄位名稱、欄位的類型,以及資料表鍵的結構(如果有的話)。

雖然沒有字面上的表格語法,但提供了數個標準函式庫函式來構建它們。 表格也可以利用內在函數 #table來構造。

以下範例從欄位名稱清單和列清單中構建一個表格。 結果的表格將包含兩欄 type any 和三列。

#table({"x", "x^2"}, {{1,1}, {2,4}, {3,9}})

#table 也可以用來指定完整的資料表類型:

#table(
    type table [Digit = number, Name = text],  
    {{1,"one"}, {2,"two"}, {3,"three"}} 
    )

此處新資料表值有一個表型別,指定欄位名稱與欄位類型。

以下運算子定義為表格值:

Operator Result
x = y Equal
x <> y 不相等
x & y Concatenation
x ?? y Coalesce

資料表串接會對齊同名欄位,並填 null 補只出現在其中一個運算元表中的欄位。 以下範例說明表格串接:

  #table({"A","B"}, {{1,2}}) 
& #table({"B","C"}, {{3,4}})
A B C
1 2 null
null 3 4

表值的原生型態是一種自訂型態(源自內在型別 table),列出欄位名稱,指定所有欄位類型為任意,且沒有鍵值。 (詳情請參閱 表格類型 。)

Function

函數值是將一組參數映射到單一值的值。 函數值的細節詳見函數部分

類型

型別值是用來分類其他值的值。 類型值的細節詳見「類型」一節