Поделиться через


Значения

Значение — это данные, создаваемые путем оценки выражения. В этом разделе описываются типы значений на языке 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("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 Равный
x <> y Не равно
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 равный
x <> y Не равно
x + y Сумма
x - y Расхождение
x * y Продукт
x / y Знаменатель
x ?? y Coalesce
+x Унарный плюс
-x Отрицание

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

Время

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

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

#time(hour, minute, second)

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

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

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

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

Оператор Результат
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.

Дата

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

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

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

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

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

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

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

DateTimeZone

Значение datetimezone содержит дату и часовой пояс. Часовой пояс закодирован как количество минут смещения от UTC, что определяет, на сколько минут часть времени в дате и времени должна быть смещена от Всемирного согласованного времени (UTC). Минимальное количество минут смещения от UTC равно -840, что соответствует смещению UTC на -14:00, то есть на 14 часов раньше, чем 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 Не равно
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 Равно
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 Доля длительности
x / y duration duration Числовое отношение длительностей

Собственный тип значений длительности — это встроенный тип duration.

Текст

Текстовое значение представляет последовательность символов Юникода. Текстовые значения имеют литеральную форму, соответствующую следующей грамматике:

_text-буквальное значение:
       "Выбор текстовых литеральных символов"
символы текстового литерала:
      символ-текстового-литерала символы-текстового-литераланеобязательно
символ-текстового-литерала:
      один текстовый символ
      последовательность экранирования символов
      последовательность-экранирования-двойных-кавычек
одиночный-текстовый-символ:

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

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

"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.

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

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

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

Оператор Результат
x = y Равный
x <> y Не равно
x >= y Больше или равно
x > y Больше чем
x < y Меньше
x <= y Меньше или равно
x ?? y Coalesce

Собственный тип двоичных значений — это встроенный тип binary.

Список

Значение списка — это значение, которое создает последовательность значений при перечислении. Значение, созданное списком, может содержать любое значение, включая список. Списки можно создать с помощью синтаксиса инициализации следующим образом:

list-expression:
      { список-элементовопция }
список-элементов:
      элемент
      элемент-список
,
предмет
      выражение
      выражение
..выражение

Ниже приведен пример выражения-списка, которое определяет список с тремя текстовыми значениями: "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 Равно
x <> y Не равно
x & y Объединить
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-name
=
имя поля
      общий идентификатор
      quoted-identifier

В следующем примере создается запись с полем x со значением 1и полем y со значением 2.

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

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

Оператор Результат
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.

В следующем примере создается таблица из списка имен столбцов и списка строк. Результирующая таблица будет содержать два столбца 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 Б C
1 2 null
null 3 4

Собственный тип табличных значений — это пользовательский тип таблицы (производный от встроенного типа table), который перечисляет имена столбцов, указывает, что все типы столбцов являются любыми и не имеют ключей. (Дополнительные сведения о типах таблиц см. в разделе Типы таблиц.)

Функция

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

Тип

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