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

person Pipo    schedule 17.10.2018    source источник


Ответы (2)


Тип привязки — это когда вы используете функцию «нравится» (обратите внимание, что вы также можете использовать «как {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 может быть переопределен в потомке с другими типами.

person Jocelyn    schedule 17.10.2018

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

В вашем примере можно было бы иметь потомка класса 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 приведет к сбою, поскольку в классе TERMINAL_COLOR нет метода touch_color.

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

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

person Alexander Kogtenkov    schedule 17.10.2018