0

我正在尝试创建一些终端日志记录颜色,以便能够更清楚地看到我的错误。这样做在我看来很明显我必须创建如下常量。因为我不想每次调用常量时都创建一个实例,所以这样做对我来说是有意义的,但编译器似乎与我的概念不同......

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
4

2 回答 2

3

事实上,一旦函数不允许返回锚定类型或正式泛型类型的值。原因在于一次函数的语义:它的主体只执行一次(我将通过递归省略更复杂的情况),而不管当前的对象类型如何。

在您的示例中,可以有一个 class 的后代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

因为blackreturn like Current,所以两个赋值都是有效的:类型blackTERMINAL_COLOR在第一个调用中,而TOUCH_PAD_COLOR- 在第二个调用中。但是,该功能的主体black只执行一次,即在第一次调用中。计算对象的类型是TERMINAL_COLOR. 在第二个赋值中,返回先前计算的对象而不执行函数体black。对象的类型还是一样的:TERMINAL_COLOR. 但是现在这个对象被附加到ptype 的实体上TOUCH_PAD_COLOR。调用p,例如p.touch_color会导致崩溃,因为touch_color类中没有方法TERMINAL_COLOR

至于术语,锚定类型表示根据其他一些实体声明的类型。例如,like Current指当前类的类型。

免责声明。有不同种类的一次性特征,上面的场景处理最常见的情况。

于 2018-10-17T15:32:52.987 回答
2

锚类型是当您使用“like 功能”时(注意您也可以使用“like {FOO}.bar”)。

另外,不要忘记“一次”是“每个班级一次”(不是按类型)。这就是为什么一次函数的结果类型不能使用任何正式的泛型。例如

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

(create {FOO [INTEGER]}).bar将返回与 相同的对象(create {FOO [STRING]}).bar

所以,现在如果在 FOO 类中bar返回G,它会带来麻烦,因为没有办法返回符合任何形式(整数、字符串、...)的值。

这就是为什么泛型被禁止用于一次结果类型。

相同的逻辑适用于锚类型like feature_name,因为feature_name可以在后代中与其他类型一起重新定义。

于 2018-10-17T15:39:47.790 回答