Values

Значение — это данные, создаваемые путем оценки выражения. В этом разделе описываются типы значений на языке M. Каждый тип значения связан с литеральным синтаксисом, набором значений, которые имеют такой вид, набор операторов, определенных для этого набора значений, и встроенным типом, назначенным только что созданным значениям.

Вид Литерал
Null null
Логическое true    false
Число 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)
Текст "hello"
Binary #binary("AQID")
Список {1, 2, 3}
Запись [ A = 1, B = 2 ]
Таблицу #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 Equal
x <> y Not equal
x ?? y Coalesce

Собственный null тип значения — это встроенный тип null.

Логический

Логическое значение используется для логических операций со значением true или false. Логическое значение записывается с помощью литерала true и false. Для логических значений определены следующие операторы:

Оператор Результат
x > y Больше
x >= y Больше или равно
x < y Меньше
x <= y Меньше или равно
x = y Equal
x <> y Not equal
x or y Условный логический ИЛИ
x ?? y Coalesce
x and y Условный логический И
not x Логическое НЕ

Собственный тип логических значений (true и false) является встроенным типом 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 (но может сохранить большую точность). Двойное представление соответствует стандарту двойной точности IEEE 64-разрядной точности для арифметики двоичной с плавающей запятой, определенной в [IEEE 754-2008]. (The Двойное представление имеет приблизительный динамический диапазон от 5,0 x 10324 до 1,7 x 10 308 с точностью 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 Equal
x <> y Not equal
x + y Sum
x - y Расхождение
x * y Товар
x / y Знаменатель
x ?? y Coalesce
+x Унарный плюс
-x Отрицание

Собственный тип значений чисел является встроенным типом number.

Time

Значение времени сохраняет непрозрачное представление времени дня. Время закодировано как число тиков с полуночи, которое подсчитывает число 100-наносекунд, которые истекли на 24-часовых часах. Максимальное число галок с полуночи соответствует 23:59:59.99999999999 часов.

Хотя в некоторых случаях нет литерального синтаксиса, для их создания предоставляются несколько стандартных функций библиотеки. Время также можно создать с помощью встроенной функции #time:

#time(hour, minute, second)

Вызывается следующая ошибка или ошибка с кодом Expression.Error причины:

0 ≤ час ≤ 24
0 ≤ минуты ≤ 59
0 ≤ секунды ≤ 59

Кроме того, если час = 24, то минута и вторая должны быть нулевыми.

Для значений времени определяются следующие операторы:

Оператор Результат
x = y Equal
x <> y Not equal
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.

Дата

Значение даты сохраняет непрозрачное представление определенного дня. Дата закодирована как число дней с эпохи, начиная с 1 января 0001 г. в григорианском календаре. Максимальное число дней с эпохи 3652058, соответствующее 31 декабря 9999 года.

Хотя для дат нет литерального синтаксиса, для их создания предоставляются несколько стандартных функций библиотеки. Даты также могут быть созданы с помощью встроенной функции #date:

#date(year, month, day)

Вызывается следующая ошибка или ошибка с кодом Expression.Error причины:

1 ≤ год ≤ 9999
1 ≤ месяца ≤ 12
1 ≤ день ≤ 31

Кроме того, день должен быть допустимым для выбранного месяца и года.

Для значений дат определены следующие операторы:

Оператор Результат
x = y Equal
x <> y Not equal
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:

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

Должно соблюдаться следующее условие или будет выдана ошибка с кодом причины Expression.Error: 1 ≤ год ≤ 9999
1 ≤ месяца ≤ 12
1 ≤ день ≤ 31
0 ≤ час ≤ 23
0 ≤ минуты ≤ 59
0 ≤ секунды ≤ 59

Кроме того, день должен быть допустимым для выбранного месяца и года.

Для значений datetime определены следующие операторы:

Оператор Результат
x = y Equal
x <> y Not equal
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 — это встроенный тип datetime.

DateTimeZone

Значение datetimezone содержит дату и часовой пояс. Часовой пояс закодирован в виде числа минут смещения от UTC, которое подсчитывает количество минут, в течение которого часть времени даты и времени должна быть смещения от универсального координированного времени (UTC). Минимальное количество минут смещения от UTC равно -840, представляющее смещение UTC в формате -14:00 или 14:00 ранее, чем в формате UTC. Максимальное количество минут смещения от UTC — 840, соответствующее смещением UTC 14:00.

Хотя для даты и времени нет литерального синтаксиса, для их создания предоставляются некоторые стандартные функции библиотеки. Также можно создать даты и часовой пояс с помощью встроенной функции #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.

Для значений datetimezone определены следующие операторы:

Оператор Результат
x = y Equal
x <> y Not equal
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 секунд вперед во времени.

Хотя для длительности нет литерального синтаксиса, для их создания предоставляются несколько стандартных функций библиотеки. Длительность также можно создать с помощью встроенной функции #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 Equal
x <> y Not equal
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-литерал:
      " символы-текстового-литераланеобязательно"
символы-текстового-литерала:
      символ-текстового-литерала символы-текстового-литераланеобязательно
символ-текстового-литерала:
      одиночный-текстовый-символ
      escape-последовательность-символов
      escape-последовательность-двойных-кавычек
одиночный-текстовый-символ:

      Любой символ, кроме " (U+0022) или (U+0023) за # которым следует ( () (U+0028)
double-quote-escape-sequence:
      "" (U+0022, U+0022)

Ниже приведен пример текстового значения:

"ABC" // the text value ABC

Следующие операторы определяются по текстовым значениям:

Оператор Результат
x = y Equal
x <> y Not equal
x >= y Больше или равно
x > y Больше
x < y Меньше
x <= y Меньше или равно
x & y Объединение
x ?? y Coalesce

Собственный тип текстовых значений является встроенным типом text.

Binary

Двоичное значение представляет последовательность байтов.

Хотя для двоичных значений нет литерального синтаксиса, для их создания предоставляются несколько стандартных функций библиотеки. Двоичные значения также могут быть созданы с помощью встроенной функции #binary.

В следующем примере создается двоичное значение из списка байтов:

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

Следующие операторы определяются для двоичных значений:

Оператор Результат
x = y Equal
x <> y Not equal
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

Для списков определены следующие операторы:

Оператор Результат
x = y Equal
x <> y Not equal
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
      поле
,список-полей
Поле:
      имя-поля
=выражение
имя-поля:
      обобщенный-идентификатор
      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 Equal
x <> y Not equal
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.

В следующем примере создается таблица из списка имен столбцов и списка строк. Результирующая таблица будет содержать два столбца 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 Equal
x <> y Not equal
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), который перечисляет имена столбцов, указывает, что все типы столбцов являются любыми и не имеют ключей. (Дополнительные сведения о типах таблиц см. в разделе Типы таблиц.)

Функция

Значение функции — это значение, которое сопоставляет набор аргументов с одним значением. Сведения о значениях функций описаны в разделе "Функции".

Тип

Значение типа — это значение, которое классифицирует другие значения. Сведения о значениях типов описаны в разделе "Типы".