Определение типа в операторах конструкторах

Начиная с ABAP 7.4. нам стали доступны операторы конструкторы, такие как:

Одной из особенностей данных операторов является возможность неявного определения типа через #, из-за чего у некоторых разработчиков часто возникают ошибки связанные с их использованием.

Далее рассмотрим типичные из них.

Возьмём оператор COND (релевантно и для SWITCH):

Результатом данного выражения будет — *.

If the operand type is not fully identifiable, an operand with a statically identifiable type must be specified after the first THEN (except when passing the constructor parameter to an actual parameter with generically typed formal parameter). This type is then used. In particular, THROWs cannot then be specified after THEN.

А все из-за того что, тип будет выведен неявно из первого условия после THEN, т.е. будет соответствовать константе space. Константа space в ABAP объявлена с типом C длиной 1 символ. Условие 1 = 2 очевидно не будет выполнено и переменной lv_val с типом C и длиной 1 символ будет присвоено значение 777. А согласно правилам конвертации, если при преобразовании числа к символьному типу оно не влезает по размеру, результат будет заменён * (некоторые говорят в таких случаях «SAP celebrates christmas»).

Другой частой ошибкой является использование оператора REDUCE #:

Результат выражения будет — 0.

Тип временной переменной sum будет выведен исходя из присвоения ( = 0) — в данном случае integer. REDUCE так же возвратит integer исходя из типа переменной sum.

Но даже если явным образом объявить тип переменной после REDUCE, результат будет тот же:

Результат остаётся прежним, т.к. переменная sum все еще имеет тип integer, соответственно при суммировании срабатывает целочисленная арифметика, после чего результат целогочисленного суммирования в поле sum присваивается к результату с типом decfloat34.

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

А еще лучше указывать тип и там и там:

В целом общая рекомендация что по данным примерам, что в целом: если что-то можно сделать явным образом — лучше сделать это явно, чем полагаться на неявное поведение выполняемое системой за вас 🙂

1 комментарий

  1. Вот и я обнаружил это на своём личном опыте
    cond #( when s_vkorg is initial then ‘VK’ else conv string( s_vkorg[ 1 ]-low ) ) возвращает вместо 2156 «21»

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *