Eiffel: локальная декларация в или и не смогла скомпилировать - PullRequest
0 голосов
/ 08 октября 2018

Компилятор жалуется на неизвестный идентификатор, кажется, что он не распознает ни одно из моих нескольких объявлений, где я ошибаюсь?

if attached {INTEGER_REF} field.item as l_int
        or attached {INTEGER_64} field.item as l_int
        or ( attached {TUPLE} field.item as l_tuple and then attached {INTEGER_64} l_tuple.item (1) as l_int ) then
    Result.put_integer (l_int.to_integer_64, primary_key_db_column_name)
elseif attached {STRING} field.item as l_s then
    Result.put_string (l_s, primary_key_db_column_name)
end

enter image description here

Обновление

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

Но, похоже, это выражение является действительным

if attached a.b as l_b and then attached l_b.c as l_c then
    l_c.is_available_in_this_scope
    l_b.is_available_in_this_scope
else
    io.putstring ("you are wrong dear and either l_b and l_c are not available!")
end

Пока это нет!

if attached a.b as l_b and then attached l_b.c as l_c
        or attached a.x as l_b and then attached l_x.d as l_c then
    l_c.is_available_in_this_scope -- Compiler complain about l_c
    l_b.is_available_in_this_scope -- Compiler complain about l_b
else
    io.putstring ("you are wrong dear and either l_b and l_c are not available!")
end

Смой код

Этот компилируется

    if attached {INTEGER_REF} field.item as l_int then
        Result.put_integer (l_int.to_integer_64, primary_key_db_column_name)
    elseif attached {INTEGER_64} field.item as l_int then
        Result.put_integer (l_int, primary_key_db_column_name)
    elseif attached {TUPLE} field.item as l_tuple and then attached {INTEGER_64} l_tuple.item (1) as l_int then
        Result.put_integer (l_int, primary_key_db_column_name)
    elseif attached {STRING} field.item as l_s then
        Result.put_string (l_s, primary_key_db_column_name)
    else
        logger.write_error ("to_json-> Type not found in matching:" + field.item.out)
        check
            not_found_item_type: False
        end
    end

Пока этот не

if attached {INTEGER_REF} field.item as l_int then
    Result.put_integer (l_int.to_integer_64, primary_key_db_column_name)
elseif attached {INTEGER_64} field.item as l_int
        or attached {TUPLE} field.item as l_tuple and then attached {INTEGER_64} l_tuple.item (1) as l_int then
    Result.put_integer (l_int, primary_key_db_column_name) -- Unknown identifier `l_int`
elseif attached {STRING} field.item as l_s then
    Result.put_string (l_s, primary_key_db_column_name)
else
    logger.write_error ("to_json-> Type not found in matching:" + field.item.out)
    check
        not_found_item_type: False
    end
end

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

Объектные тесты имеют границы.Обозначая объектный тест OT, его область действия

if OT         then A else B end
if OT and ... then A else B end
if OT or  ... then C else B end

составляет всего A.Следовательно, для дизъюнкции область действия пуста, и вы не можете использовать соответствующий локальный тест объекта в любой из ветвей.

Если в условном выражении есть два объектных теста, их области действия могут перекрываться или нет:

if OT1 and      OT2 then A else B end
if OT1 and then OT2 then A else B end
if OT1 or       OT2 then C else B end

Здесь, как и прежде, локальная переменная проверки объекта OT1 имеет область действия A.Кроме того, для and then область действия включает OT2, в частности, OT2 может использовать локальное значение OT1.По той же причине OT2 не может использовать один и тот же локальный объектный тест OT1.

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

if attached e1 as x and      attached e2_without_x as y then use_x_and_y else B end
if attached e1 as x and then attached e2_with_x    as y then use_x_and_y else B end
if attached e1 as x or       attached e2_without_x as y then no_x_no_y   else B end

Было бы все еще возможно переписать пример только с одной первой ветвью , если тип всех задействованных выражений равенто же самое (это не так, потому что есть типы INTEGER_64 и INTEGER_REF):

if attached
       if attached {INTEGER_64_REF} field.item as i then
           i
       elseif
           attached {TUPLE} field.item as t and then
           t.count > 0 and then
           attached {INTEGER_64_REF} t.item (1) as i
       then
           i
       else
           Void
       end
   as j
then
   -- Use j
...

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

0 голосов
/ 09 октября 2018

Ну, для начала вы не можете использовать один и тот же идентификатор (l_int) для нескольких локальных тестовых объектов в одной и той же области видимости.

...