閱讀英文

共用方式為


值是藉由評估運算式所產生的資料。 本節描述 M 語言中的值種類。 每個種類的值都與常值語法、一組屬於該種類的值、一組在該值上定義的運算子,以及歸屬於新建立值的內建類型建立關聯。

種類 常值
Null null
邏輯 true    false
Number 0    1    -1    1.5    2.3e-5
Time #time(09,15,00)
日期 #date(2013,02,26)
DateTime #datetime(2013,02,26, 09,15,00)
DateTimeZone #datetimezone(2013,02,26, 09,15,00, 09,00)
期間 #duration(0,1,30,0)
Text "hello"
二進位 #binary("AQID")
清單​​ {1, 2, 3}
錄製 [ A = 1, B = 2 ]
Table #table({"X","Y"},{{0,1},{1,0}})
Function (x) => x + 1
類型 type { number }    type table [ A = any, B = text ]

下列章節將詳述每個值種類。 類型和類型歸屬,正式定義於類型中。 函式值定義於函式中。 下列章節列出針對每個值種類所定義的運算子,並提供範例。 運算子語義的完整定義,位於運算子中。

Null

「Null 值」用來表示缺少的值,或值為不確定或未知狀態。 Null 值使用 null 常值撰寫。 下列運算子針對 Null 值定義:

運算子 結果
x > y 大於
x >= y 大於或等於
x < y 小於
x <= y 小於或等於
x = y 等於
x <> y 不等於
x ?? y Coalesce

null 值的原生類型是內建類型 null

邏輯

「邏輯值」用於布林運算,具有 True 或 False 值。 邏輯值使用 truefalse 常值撰寫。 下列運算子針對邏輯值定義:

運算子 結果
x > y 大於
x >= y 大於或等於
x < y 小於
x <= y 小於或等於
x = y 等於
x <> y 不等於
x or y 條件邏輯 OR
x ?? y Coalesce
x and y 條件邏輯 AND
not x 邏輯 NOT

邏輯值 (truefalse) 的原生類型是 logical 內建類型。

數值

「數字值」用於數值和算數運算。 下列是數字常值的範例:

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 精確度來表示 (但可能會保留更多有效位數)。 Double 表示法與 [IEEE 754-2008] 中所定義二進位浮點算術的 IEEE 64 位元雙精確度標準一致。 (Double 表示法具有大約從 5.0 x 10324 到 1.7 x 10308 的動態範圍,精確度為 15-16 位數。)

下列特殊值也會視為「數字」值:

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

  • 正無限 (#infinity) 和負無限 (-#infinity)。 無限是藉由將非零數字除以零之類的運算來產生。 例如,1.0 / 0.0 會產生正無限,-1.0 / 0.0 會產生負無限。

  • Not-a-Number 值 (#nan) 通常縮寫為 NaN。 NaN 是由不正確的浮點運算所產生,例如零除以零。

二進位數學運算會使用「精確度」來執行。 精確度會決定要將運算元四捨五入的定義域,以及要在其中執行作業的定義域。 如果沒有明確指定精確度,則會使用「雙精確度」來執行這類作業。

  • 如果數學運算的結果太小,無法用於目標格式,則運算的結果會變成正零或負零。

  • 如果數學運算的結果太大,無法用於目標格式,則運算的結果會變成正無限或負無限。

  • 如果數學運算無效,則運算的結果會變成 NaN。

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

下列運算子針對數值定義:

運算子 結果
x > y 大於
x >= y 大於或等於
x < y 小於
x <= y 小於或等於
x = y 等於
x <> y 不等於
x + y Sum
x - y 差數
x * y Products
x / y 商數
x ?? y Coalesce
+x 一元加號
-x 否定

數值的原生類型是內建類型 number

Time

「時間值」會儲存一天中時間的不透明表示。 時間會編碼為「從午夜起的刻度」數,以 24 小時制時間來計算 100 奈秒刻度數。 「從午夜起的刻度」數會對應至 23:59:59.9999999 小時。

雖然 times 沒有常值語法,但會提供數個標準程式庫函式來加以建構。 Times 也可以使用 #time 內建函式來建構:

#time(hour, minute, second)

下列項目必須保留,否則會以原因代碼 Expression.Error 引發錯誤:

0 ≤ 小時 ≤ 24
0 ≤ 分鐘 ≤ 59
0 ≤ 秒 ≤ 59

此外,如果 hour = 24,則 minute 和 second 必須為零。

下列運算子針對時間值定義:

運算子 結果
x = y 等於
x <> y 不等於
x >= y 大於或等於
x > y 大於
x < y 小於
x <= y 小於或等於
x ?? y Coalesce

下列運算子允許其一或兩個運算元都是日期:

運算子 左運算元 右運算元 意義
x + y time duration 依據期間位移後的日期
x + y duration time 依據期間位移後的日期
x - y time duration 依據負期間位移後的日期
x - y time time 日期之間的期間
x & y date time 合併後的日期時間

類型值的原生類型是內建類型 time

Date

「時間值」會儲存特定日期的不透明表示。 日期是以「紀元起算的天數」來編碼,從西曆的 0001 年 1 月 1 日開始。 自紀元起算的天數上限為 3652058,對應於 9999 年 12 月 31 日。

雖然 dates 沒有常值語法,但會提供數個標準程式庫函式來加以建構。 Dates 也可以使用 #date 內建函式來建構:

#date(year, month, day)

下列項目必須保留,否則會以原因代碼 Expression.Error 引發錯誤:

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

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

下列運算子針對日期值定義:

運算子 結果
x = y 等於
x <> y 不等於
x >= y 大於或等於
x > y 大於
x < y 小於
x <= y 小於或等於
x ?? y Coalesce

下列運算子允許其一或兩個運算元都是日期:

運算子 左運算元 右運算元 意義
x + y date duration 依據期間位移後的日期
x + y duration date 依據期間位移後的日期
x - y date duration 依據負期間位移後的日期
x - y date date 日期之間的期間
x & y date time 合併後的日期時間

日期值的原生類型是內建類型 date

Datetime

「日期時間值」同時包含日期和時間。

雖然 datetimes 沒有常值語法,但會提供數個標準程式庫函式來加以建構。 Datetimes 也可以使用內建函式 #datetime 來建構:

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

下列項目必須保留,否則會以原因代碼 Expression.Error 引發錯誤:1 ≤ year ≤ 9999
1 ≤ 月 ≤ 12
1 ≤ 日 ≤ 31
0 ≤ 小時 ≤ 23
0 ≤ 分鐘 ≤ 59
0 ≤ 秒 ≤ 59

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

下列運算子針對日期時間值定義:

運算子 結果
x = y 等於
x <> y 不等於
x >= y 大於或等於
x > y 大於
x < y 小於
x <= y 小於或等於
x ?? y Coalesce

下列運算子允許其一或兩個運算元都是日期時間:

運算子 左運算元 右運算元 意義
x + y datetime duration 依據期間位移後的日期時間
x + y duration datetime 依據期間位移後的日期時間
x - y datetime duration 依據負期間位移後的日期時間
x - y datetime datetime 日期時間之間的期間

日期時間值的原生類型是內建類型 datetime

DateTimeZone

datetimezone 值包含日期時間和時區。 「時區」會以「與 UTC 的分鐘數時差」來編碼,其會計算「日期時間」時間部分與國際標準時間 (UTC) 的分鐘數時差。 「與 UTC 的分鐘數時差」最小數目為 -840,代表 -14:00 的 UTC 時差,或比 UTC 早十四小時。 「與 UTC 的分鐘數時差」最大數目為 840,對應於 14:00 的 UTC 時差。

雖然 datetimezones 沒有常值語法,但會提供數個標準程式庫函式來加以建構。 Datetimezones 也可以使用內建函式 #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 ≤ offset-hours ≤ 14
-59 ≤ offset-minutes ≤ 59

此外,日期必須適用於所選的月份和年份,如果 offset-hours = 14,則 offset-minutes <= 0,而如果 offset-hours = -14,則 offset-minutes >= 0。

下列運算子針對 datetimezone 值定義:

運算子 結果
x = y 等於
x <> y 不等於
x >= y 大於或等於
x > y 大於
x < y 小於
x <= y 小於或等於
x ?? y Coalesce

下列運算子允許其一或兩個運算元都是 datetimezone:

運算子 左運算元 右運算元 意義
x + y datetimezone duration 依據期間位移後的日期時區
x + y duration datetimezone 依據期間位移後的日期時區
x - y datetimezone duration 依據負間位移後的日期時區
x - y datetimezone datetimezone 日期時區之間的期間

datetimezone 值的原生類型是內建類型 datetimezone

持續時間

「持續時間值」會儲存時間軸上兩個點之間距離的不透明表示,以 100 奈秒刻度數來測量。 「持續時間」的範圍可以是正數或負數,其正值表示時間往前的進度,負值則代表時間往後的進度。 可以在「持續時間」內儲存的最小值為 -9,223,372,036,854,775,808 刻度,或 10,675,199 天 2 小時 48分鐘 05.4775808 秒往前的時間。 可以在「持續時間」內儲存的最大值為 9,223,372,036,854,775,807 刻度,或 10,675,199 天 2 小時 48 分鐘 05.4775807 秒往後的時間。

雖然 durations 沒有常值語法,但會提供數個標準程式庫函式來加以建構。 Durations 也可以使用內建函式 #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

下列運算子在持續時間值上定義:

運算子 結果
x = y 等於
x <> y 不等於
x >= y 大於或等於
x > y 大於
x < y 小於
x <= y 小於或等於
x ?? y Coalesce

此外,下列運算子允許其一或兩個運算元都是持續時間值:

運算子 左運算元 右運算元 意義
x + y datetime duration 依據期間位移後的日期時間
x + y duration datetime 依據期間位移後的日期時間
x + y duration duration 期間的總和
x - y datetime duration 依據負期間位移後的日期時間
x - y datetime datetime 日期時間之間的期間
x - y duration duration 期間的差異
x * y duration number 期間乘以 N 次
x * y number duration 期間乘以 N 次
x / y duration number 期間的分數

持續時間值的原生類型是內建類型 duration

Text

「文字」值表示 Unicode 字元序列。 文字值的常值格式符合下列文法:

_text-literal:
      " text-literal-charactersopt "
text-literal-characters:
      text-literal-character text-literal-charactersopt
text-literal-character:
      single-text-character
      character-escape-sequence
      double-quote-escape-sequence
single-text-character:

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

下列為「文字」值的範例:

"ABC" // the text value ABC

下列運算子在「文字」值上定義:

運算子 結果
x = y 等於
x <> y 不等於
x >= y 大於或等於
x > y 大於
x < y 小於
x <= y 小於或等於
x & y 串連
x ?? y Coalesce

文字值的原生類型是內建類型 text

二進位

「二進位值」代表位元組序列。

雖然二進位值沒有常值語法,但會提供數個標準程式庫函式來加以建構。 二進位值也可以使用內建函式 #binary 來建構。

下列範例會從位元組清單中建構二進位值:

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

下列運算子在「二進位」值上定義:

運算子 結果
x = y 等於
x <> y 不等於
x >= y 大於或等於
x > y 大於
x < y 小於
x <= y 小於或等於
x ?? y Coalesce

二進位值的原生類型是內建類型 binary

清單

「清單值」是會在列舉時產生一系列值的值。 清單所產生值可以包含任何類型的值,包括清單。 您可使用初始化語法來建構清單,如下所示:

list-expression:
      { item-listopt }
item-list:
      項目
      item
, item-list
item:
      expression
      運算式
.. 運算式

下列是 list-expression 的範例,其會以三個文字值來定義清單:"A""B""C"

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

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

  • 清單的項目不會在存取之前進行評估。
  • 雖然使用清單語法所建立清單值會以其顯示在 item-list 中的順序來產生項目,但在一般情況下,從程式庫函式傳回的清單,可能會在每次列舉時產生不同集合或不同數目的值。

若要在清單中包含整數序列,可使用 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

下列運算子針對清單定義:

運算子 結果
x = y 等於
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-expression:
      [ field-listopt ]
field-list:
      field
      field
, field-list
field:
      field-name
= expression
field-name:
      generalized-identifier
      quoted-identifier

下列範例使用名為 x 且值為 1 的欄位,以及名為 y 且值為 2 的欄位來建構記錄。

[ x = 1, y = 2 ]

下列範例使用以巢狀記錄值命名的 a 欄位來建構記錄。 此巢狀記錄具有名為 b 的欄位,其值為 2

[ a = [ b = 2 ] ]

評估記錄運算式時會發生下列情況:

  • 指派給每個欄位名稱的運算式,會用來判斷相關聯欄位的值。

  • 如果指派給欄位名稱的運算式在評估時產生值,則該值會成為所產生記錄的欄位值。

  • 如果指派給欄位名稱的運算式在評估時引發錯誤,則引發錯誤的事實,會連同欄位及引發的錯誤值一起記錄。 對該欄位的後續存取,將會導致重新引發錯誤,並包含記錄的錯誤值。

  • 運算式是在父環境之類的環境中評估,僅合併與記錄每個欄位其值對應的變數,除了用於初始化的變數以外。

  • 在存取對應的欄位之前,不會評估記錄中的值。

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

  • 運算式結果是具有空白中繼資料記錄的記錄值。

  • 記錄內欄位的順序,是以其出現在 record-initializer-expression 中的順序來定義。

  • 所指定每個欄位名稱在記錄內都必須是唯一的,否則會發生錯誤。 名稱會使用序數比較來進行比較。

    [ 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 ]

下列運算子針對記錄定義:

運算子 結果
x = y 等於
x <> y 不等於
x & y 合併
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"}} 
    )

在這裡,新的資料表值有一個資料表類型,其會指定資料行名稱和資料行類型。

下列運算子針對資料表值定義:

運算子 結果
x = y 等於
x <> y 不等於
x & y 串連
x ?? y Coalesce

資料表串連會將名稱類似的資料行對齊,並會為僅出現在一個運算元資料表的資料行填入 null。 下列範例說明資料表串連:

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

資料表值的原生類型是自訂資料表類型 (衍生自內建類型 table),其會列出資料行名稱、指定所有資料行類型為任何類型,且沒有索引鍵。 (如需資料表類型的詳細資訊,請移至資料表類型。)

函式

「函式值」是將一組引數對應到單一值的值。 「函式」值的詳細資料於函式中描述。

類型

「類型值」是分類其他值的值。 「類型」值的詳細資料於類型中描述。