Eiffel: однажды функция имеет общий или привязанный результат. Попытка создания констант

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

A once function has generic or anchored result что такое anchored результат?

Поскольку у компилятора всегда последнее слово, а у меня передний план, почему я ошибаюсь, и он прав?

class
    TERMINAL_COLOR

create
    make

feature -- Initialization

    make (a_fg: like foreground; a_bg: like background)
        do
            foregound := a_fg
            background := a_bg
        end

feature -- Status report

    foreground: INTEGER

    background: INTEGER

feature -- Colors

    Black: like Current
        once -- compiler doesn't agree with me
            create Result.make (30, 40)
        ensure
            instance_free: class
        end

end

2 ответа

Решение

Тип привязки - это когда вы используете "подобную функцию" (обратите внимание, что вы также можете использовать "like {FOO}.bar").

Кроме того, не забывайте, что "Один раз" - "один раз на класс" (не по типу). Вот почему тип результата для функции Once не может использовать какой-либо формальный шаблон. Например

class FOO [G]
feature
    bar: STRING
        once
           Result := generating_type
        end
end

(create {FOO [INTEGER]}).bar вернет тот же объект, что и (create {FOO [STRING]}).bar,

Итак, теперь, если bar вернется G в классе FOO это вызовет проблемы, поскольку нет способа вернуть значение, соответствующее любому формальному (INTEGER, STRING, ...).

Поэтому общий тип запрещен для одного типа результата.

Та же логика применяется к типу привязки, такой как like feature_name, как feature_name может быть переопределено в потомке с другими типами.

Действительно, если функциям не разрешено возвращать значение привязанного типа или формального универсального типа. Причина заключается в семантике функции Once: ее тело выполняется только один раз (я опускаю более сложные случаи с рекурсией) независимо от текущего типа объекта.

В вашем примере было бы возможно иметь потомка класса TERMINAL_COLOR, сказать, TOUCH_PAD_COLOR (что бы это ни значило):

class
    TOUCH_PAD_COLOR
inherit
    TERMINAL_COLOR
create
    make
feature
    touch_color: like Current
            -- Color for visual indication of user interaction.
        ...
end

Давайте посмотрим, что происходит в следующем коде:

t: TERMINAL_COLOR
p: TOUCH_PAD_COLOR
...
t := {TERMINAL_COLOR}.black
p := {TOUCH_PAD_COLOR}.black

Так как black возвращается like Current оба назначения действительны: тип black является TERMINAL_COLOR в первом звонке и TOUCH_PAD_COLOR - во-вторых. Тем не менее, тело функции black выполняется только один раз, а именно при первом вызове. И тип вычисляемого объекта TERMINAL_COLOR, Во втором присваивании ранее вычисленный объект возвращается без выполнения тела функции black, Тип объекта остается прежним: TERMINAL_COLOR, Но теперь этот объект прикреплен к сущности p типа TOUCH_PAD_COLOR, Звонить на p например, p.touch_color приведет к сбою, потому что нет никакого метода touch_color в классе TERMINAL_COLOR,

Что касается терминологии, привязанные типы обозначают типы, объявленные в терминах некоторых других объектов. Например, like Current относится к типу текущего класса.

Отказ от ответственности. Существуют разные виды некогда функций, в приведенном выше сценарии рассматривается наиболее распространенный случай.

Другие вопросы по тегам