Реализация Eiffel Iterable на MAP?

У меня есть класс MAP:

 class MAP [KEY,VAL]
       inherit ITERABLE [KEY]

Я реализовал новый курсор внутри курсора карты, который возвращает и

MAP_ITERATOR_CURSOR [KEY]

и передает этому итерируемому курсору массив KEYS для итерации

Я реализовал класс MAP_ITERATOR_CURSOR [KEY]

 class MAP_ITERATOR_CURSOR [KEY]
       inherit ITERATION_CURSOR [KEY]

для этого класса я реализовал элемент функции: VAL, но поскольку класс был определен с помощью KEY, он не распознает VAL, как мне получить функцию элемента MAP_ITERATOR_CURSOR [KEY], чтобы вернуть VAL, связанный с ключом, который мы используем в данный момент?

Зная, что у MAP есть функция item, которая принимает ключ и возвращает VAL, связанный с этим ключом

item (k: KEY): VAL 

person Gamal Tawaf    schedule 26.06.2014    source источник


Ответы (2)


Как только MAP [KEY, VAL] наследует ITERABLE [KEY], общий параметр ITERATION_CURSOR привязывается к KEY. Однако {ITERATION_CURSOR}.item — это просто обычная функция, которая подлежит повторному объявлению, переименованию и т. д. Поэтому несколько подходов могут соответствовать вашим потребностям:

  1. Объявите MAP_ITERATOR_CURSOR иметь два формальных дженерика и объявите {MAP}.new_cursor следующим образом:

    class MAP [KEY, VAL] inherit ITERABLE [KEY] feature
        new_cursor: MAP_ITERATOR_CURSOR [KEY, VAL]
            do
                create Result.make (Current)
            end
    end
    
    class MAP_ITERATOR_CURSOR [KEY, VAL] inherit ITERATION_CURSOR [KEY]
    create make
    feature
        make (t: like target)
            do
                target := t
            end
        target: MAP [KEY, VAL]
        item: KEY ...
        value: VAL
            do
                Result := target.item (item)
            end
    end
    

    Тогда клиентский код может выглядеть как

    across map as c loop
        -- Use `c.item` of type KEY.
        -- Use `c.value` of type VAL.
    end
    
  2. Если требуется, чтобы {MAP_ITERATOR_CURSOR}.item имел тип VAL, первый способ — использовать точно такой же код, что и выше, но переименовать функцию item, полученную из ITERABLE:

    class MAP_ITERATOR_CURSOR [KEY, VAL] inherit
        ITERATION_CURSOR [KEY] rename item as key end
    ...
        key: KEY ...
        item: VAL
            do
                Result := target.item (key)
            end
    end
    

    Тогда клиентский код может выглядеть как

    across map as c loop
        -- Use `c.item` of type VAL.
        -- Use `c.key` of type KEY.
    end
    
  3. Итерацию можно выполнять по элементам типа VAL с самого начала. В этом случае фактический универсальный ITERABLE должен быть VAL:

    class MAP [KEY, VAL] inherit ITERABLE [VAL] feature
        new_cursor: MAP_ITERATOR_CURSOR [KEY, VAL]
            do
                create Result.make (Current)
            end
    end
    
    class MAP_ITERATOR_CURSOR [KEY, VAL] inherit ITERATION_CURSOR [VAL]
    create make
    feature
        make (t: like target)
            do
                target := t
            end
        target: MAP [KEY, VAL]
        item: VAL
            do
                Result := target.item (key)
            end
        key: KEY
                -- This feature can be not exported, or even not present
                -- as soon as `item` can be implemented.
    end
    

    Код клиента аналогичен случаю 2, но key может быть недоступен:

    across map as c loop
        -- Use `c.item` of type VAL.
    end
    
  4. В 3 формальное общее KEY в MAP_ITERATION_CURSOR сохранено для удобства. Его можно удалить при условии, что есть какой-то способ доступа к элементам MAP, но это может вызвать некоторые другие проблемы, связанные с доступом к MAP, соответствием и CAT-вызовами. Поэтому, хотя это потенциально осуществимо, я бы не пошел на это.

person Alexander Kogtenkov    schedule 27.06.2014

Почему бы не использовать TABLE_ITERABLE [G, K]?

cf https://svn.eiffel.com/eiffelstudio/trunk/Src/library/base/elks/kernel/table_iterable.e

person Jocelyn    schedule 26.06.2014
comment
извините, но это не сработало для той цели, которую я хочу, спасибо, есть ли способ сохранить мой первоначальный дизайн и по-прежнему возвращать значение, когда пользователь использует его по всей карте, поскольку он зацикливает it.item, чтобы вернуть значение карты? - person Gamal Tawaf; 27.06.2014