Вычисляемые выражения

Что такое вычисляемое выражение

Практически любое свойство карточки с примитивным типом (строки, числа, логическое значение) может ссылаться на вычисляемое выражение. Вычисляемая часть выражения записывается с помощью конструкции @{} и может содержать переменные, операторы и функции. Список поддерживаемых функций см. в разделе Встроенные функции.

Например:

  • Выражение "font_size": "@{common_text_size}" означает, что свойство размера шрифта карточки будет вычисляться на основе значения переменной common_text_size.

  • Чтобы увеличить размер шрифта только для некоторых карточек относительно той же переменной common_text_size, выражение можно записать так:

    "font_size": "@{sum(common_text_size, extra_size}"
    

    Теперь выражение с помощью встроенной функции sum будет складывать значения двух переменных. То же самое выражение можно записать и с помощью оператора +:

    "font_size": "@{common_text_size + extra_size}"
    

Ограничение

Выражения нельзя использовать в свойствах типов карточек, в id состояний, а так же в блоке объявления переменных variables.

Синтаксис вычисляемых выражений

В вычисляемых выражениях поддерживаются конструкции:

  • Логические операторы: ==, !=, !, >, >=, <, <=, &&, ||.
  • Арифметические операторы: +, -, *, /, %.
  • Тернарный оператор: counter > 0 ? true : 17.
  • Оператор !:: undefined_var !: fallback. В случае, когда вычисление левой части не удалось, вычисляется правая.
  • Группировка логических выражений: logging_enabled && (user_name == 'John' || user_email != '').
  • Вызов функций: mult(total_price, .83).
  • Использование вычисляемых частей внутри строк и вычисляемых выражений строчного типа: "mail: @{'@{username}@ya.ru'}" преобразуется в mail: john@ya.ru.

Шаблонные строки

Строковые параметры, в отличие от остальных, могут содержать несколько вычисляемых частей, значения которых будут конвертироваться в строку и подставляться в указанные места. Например:

"url": "https://marketplace.yandex.ru/profile/@{user_name}/orders/@{order_id}"

Внутри вычисляемого выражения можно использовать шаблонные строки, которые содержат постоянную часть и вложенные вычисляемые выражения:

"url": "@{'https://marketplace.yandex.ru/profile/@{user_name}/orders/@{order_id}'}"

Как вычисляется значение выражения

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

Вычисление в строковых параметрах

Допустим, значение параметра задано выражением: "text": "@{sum(var_a, 50)}".

Сначала будут вычислены значения аргументов функции sum, а затем будет вычислен результат этой функции.

Первый аргумент является ссылкой на переменную, и для получения ее значения будет выполнен поиск переменной сначала в локальных переменных карточки, а затем в общем контексте для нескольких карточек.

Допустим, что var_a это целочисленная переменная со значением 25. Полученное число будет сложено с другим аргументом, и результатом функции будет число 75. Далее этот результат в соответствии с контекстом свойства text будет приведен к строке, и в верстке отобразится текст "75".

Вычисление в строковых параметрах, имеющих строгий формат

Значение цвета можно задать строкой определенного формата: "text_color": "#@{str_var}".

Для таких параметров строка преобразуется в тип параметра: результат вычисляемого выражения будет сначала приведен к строке, а затем переведен к типу параметра.

Вычисление в полях с числовыми значениями

Параметры числового типа, например text_size, не поддерживают конвертацию строк в числа. Поэтому в таких параметрах необходимо использовать вычисляемые выражения, результат которых совпадает с типом параметра. Например:

  • Некорректно: "text_size": "10", "text_size": "@{str_var}".
  • Корректно: "text_size": "@{10}", "text_size": "@{int_var}".

Вычисление некорректных выражений

Допустим, параметр height имеет числовой тип. Значение параметра задано с помощью выражения @{toInteger('@{var_a}@{var_b}')}, где используется шаблонная строка с двумя переменными, результат вычисления которой будет преобразован в число с помощью функции toInteger.

Возможные ошибки при использовании такого выражения:

  1. переменные не существуют;
  2. функция toInteger не существует;
  3. функция не поддерживает аргумент типа String;
  4. возвращаемое функцией значение имеет некорректный тип или нарушает контракт, который ожидает поле height.

Во всех вышеперечисленных ситуациях значение height не может быть вычислено корректно, и система попытается обойти ошибки в следующей последовательности:

  1. попытка вычислить выражение со значениями переменных по умолчанию (например, если значение переменной var_a изменилось с 1 на one, и функция toInteger перестала работать корректно);
  2. попытка переиспользовать последнее успешно вычисленное значение;
  3. если успешно вычисленного значения нет, то выражение примет значение параметра по умолчанию (в данном случае 0).

Типы данных в выражениях

Если переменные используются в вычисляемых выражениях, то в зависимости от ситуации их значения могут приводиться к внутренним типам вычисляемых выражений.

В каких ситуациях значение переменной преобразуется во внутренний тип:

  • Переменная используется внутри шаблонной строки.
  • Переменная сравнивается со значением внутреннего типа (выражение @{subscribed == true} вернет true).

В каких ситуациях значение переменной не преобразуется во внутренний тип:

  • Выражение состоит только из ссылки на переменную: "color": "@{color_var}".
  • Сравнение двух переменных одного типа: @{color_var1 == color_var2}.

Пример:

{
    "variables": [
        {
            "name": "is_delivered",
            "type": "boolean",
            "value": true
        },
        {
            "name": "order_id",
            "type": "integer",
            "value": 17
        },
        {
            "name": "sum",
            "type": "number",
            "value": 381.3
        }
    ],
    "states": [
        ...
        {
            ...
            "text": "Order#@{order_id} delivered: @{is_delivered} total: @{sum}"
        }
        ...
    ]
}

В этом примере выражения с переменными не строковых типов используются внутри строки. В этом случае значения переменных будут преобразованы в строки. Параметр text после вычисления значений переменных будет выглядеть так: Order#17 delivered: true total: 381.3.

Внутренние типы вычисляемых выражений

  • Integer: целочисленный тип. Диапазон: -2147483648..2147483647.
  • Number: число с плавающей точкой. Диапазон: 4.9E-324..1.7976931348623157E308 (значения Nan и Infinite не поддерживаются).
  • Boolean: логический тип. Возможные значения: true, false.
  • String: строка.
  • DateTime: дата и время.

Правила приведения к внутренним типам

Значения переменных строковых и числовых типов преобразуются в аналогичные им внутренние типы. Для остальных переменных применяются такие правила:

  • тип color преобразуется в строку фиксированной длины формата #ff001122;
  • тип url преобразуется в аналогичную строку.

Операции над типами

  • Все значения одного типа можно проверять на равенство между собой (==, !=).
  • Для числовых типов и для типа DateTime доступны операции сравнения (>, >=, <, <=).
  • Числовые типы поддерживают все арифметические операторы, но следует помнить, что операции над разными типами будут приводить к ошибкам. Например, выражение @{3.81 + 5} не может быть вычислено.

Узнать больше

Следите за новостями DivKit в Telegram-канале: http://t.me/divkit_news.

Также вы можете обсуждать интересующие вас темы в сообществе пользователей DivKit в Telegram: https://t.me/divkit_community_ru.

Репозиторий DivKit

Предыдущая