Совместное использование типа с классом generi c? - PullRequest
0 голосов
/ 25 апреля 2020

Как вы объявляете переменную того же типа, что и параметр типа, используемый для создания экземпляра обобщенного c класса? Следующий код не компилируется:

class
    TEST [G, H -> INTEGER]

feature

    f (i: INDEXABLE [G, H])
        local
            y: H
        do
            y := i.lower -- Type error here.
        end

end

Компилятор говорит, что источник назначения не совместим с целью .

Ответы [ 2 ]

1 голос
/ 26 апреля 2020

Привязка типов может использоваться в следующих случаях:

feature
    f (i: INDEXABLE [G, H])
        local
            y: like i.lower
        do
            y := i.lower
        end

Иногда обобщенный тип c не используется в качестве возвращаемого типа любой доступной функции в классе, поэтому в этих случаях я хотел бы объявить фиктивная особенность, специально предназначенная для привязки:

class SOME_CLASS [G]
feature
    generic_type_anchor: G
        do
            check
                for_anchoring_only: False
                -- This method should never actually be called, only used as an anchor in type declarations
            end
        end

Это особенно полезно для сложных деревьев наследования или когда классы-потомки закрывают универсальные шаблоны, и в этом случае правильный тип не очевиден из объявленного типа. Лично я склонен использовать привязку типов всякий раз, когда значения семантически связаны, так как это помогает выразить намерение, упрощает рефакторинг (так как существует меньше повторений типов, которые по определению должны совпадать) и облегчает ковариацию.

Также в качестве сопутствующего примечания расширенные типы (например, INTEGER) нельзя использовать полиморфно (для этого вам нужна ссылка; если класс A расширен и класс B [расширенный или ссылочный] наследует A, вы не можете присвоить значение типа B переменной тип A; наследование от расширенных типов неявно не соответствует), и, кроме того, компилятор запрещает наследование от базовых c расширенных типов (INTEGER, BOOLEAN, REAL_64, et c.), поэтому Ограничение c в вашем примере не имеет смысла, потому что H никогда не может быть ничем, кроме INTEGER.

1 голос
/ 25 апреля 2020

В текущей реализации INDEXABLE [G, H] наследуется от TABLE [G, INTEGER]. В результате lower имеет тип INTEGER, а не H. И INTEGER не соответствует формальному типу generi c H класса TEST. Это объясняет ошибку.

Для меня это выглядит как ошибка в объявлении класса INDEXABLE. Вместо этого он должен наследовать от TABLE [G, H]. Затем пример кода будет скомпилирован.

...