Compiler errors Eiffel:once函数具有泛型或锚定结果。尝试创建常量

Compiler errors Eiffel:once函数具有泛型或锚定结果。尝试创建常量,compiler-errors,constants,eiffel,class-constants,Compiler Errors,Constants,Eiffel,Class Constants,我正在尝试创建一些终端日志颜色,以便能够更清楚地看到我的错误。在我看来,这样做很明显,我必须创建如下常量。因为我不想每次调用常量时都创建一个实例,所以这样做对我来说是有意义的,但是编译器似乎没有和我一样的概念 once函数具有泛型或锚定结果锚定结果是什么 因为编译器总是最后一个字,我总是最后一个字,为什么我错了,他是对的 class TERMINAL_COLOR create make feature -- Initialization make (a_fg: li

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

once函数具有泛型或锚定结果
锚定结果是什么

因为编译器总是最后一个字,我总是最后一个字,为什么我错了,他是对的

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

实际上,once函数不允许返回锚定类型或形式泛型类型的值。原因在于once函数的语义:它的主体只执行一次(我省略了更复杂的递归情况),而不考虑当前的对象类型

在您的示例中,可能会有一个类
TERMINAL\u COLOR
的后代,例如,
TOUCH\u PAD\u COLOR
(无论它是什么意思):

让我们看看以下代码中发生了什么:

t: TERMINAL_COLOR
p: TOUCH_PAD_COLOR
...
t := {TERMINAL_COLOR}.black
p := {TOUCH_PAD_COLOR}.black
由于
black
与Current一样返回
,因此这两种赋值都是有效的:第一次调用中的
black
类型为
TERMINAL\u COLOR
,第二次调用中的
TOUCH\u PAD\u COLOR
。但是,功能体
黑色
只执行一次,即在第一次调用中。并且计算对象的类型是
终端颜色
。在第二个赋值中,返回先前计算的对象,而不执行函数体
black
。对象的类型仍然相同:
TERMINAL\u COLOR
。但现在,该对象已附加到类型为触摸板颜色的实体
p
。调用
p
,例如
p.touch\u color
,会导致崩溃,因为类
终端\u color
中没有方法
touch\u color

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


免责声明。有不同种类的once功能,上面的场景处理最常见的情况。

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

在您的示例中,可能会有一个类
TERMINAL\u COLOR
的后代,例如,
TOUCH\u PAD\u COLOR
(无论它是什么意思):

让我们看看以下代码中发生了什么:

t: TERMINAL_COLOR
p: TOUCH_PAD_COLOR
...
t := {TERMINAL_COLOR}.black
p := {TOUCH_PAD_COLOR}.black
由于
black
与Current
一样返回
,因此这两种赋值都是有效的:第一次调用中的
black
类型为
TERMINAL\u COLOR
,第二次调用中的
TOUCH\u PAD\u COLOR
。但是,功能体
黑色
只执行一次,即在第一次调用中。并且计算对象的类型是
终端颜色
。在第二个赋值中,返回先前计算的对象,而不执行函数体
black
。对象的类型仍然相同:
TERMINAL\u COLOR
。但现在,该对象已附加到类型为触摸板颜色的实体
p
。调用
p
,例如
p.touch\u color
,会导致崩溃,因为类
终端\u color
中没有方法
touch\u color

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


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

锚类型是当您使用“like特性”(注意,您也可以使用“like{FOO}.bar”)

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

class FOO [G]
feature
    bar: STRING
        once
           Result := generating_type
        end
end
(创建{FOO[INTEGER]}).bar
将返回与
(创建{FOO[STRING]}.bar
相同的对象

因此,现在如果
bar
在类FOO中返回
G
,它将导致麻烦,因为无法返回符合任何形式(整数、字符串等)的值

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


同样的逻辑也适用于锚定类型,例如
like-feature\u-name
,因为
feature\u-name
可以与其他类型一起在后代中重新定义。

锚定类型是在使用“like-feature”(注意,您也可以使用“like{FOO}.bar”)

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

class FOO [G]
feature
    bar: STRING
        once
           Result := generating_type
        end
end
(创建{FOO[INTEGER]}).bar
将返回与
(创建{FOO[STRING]}.bar
相同的对象

因此,现在如果
bar
在类FOO中返回
G
,它将导致麻烦,因为无法返回符合任何形式(整数、字符串等)的值

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

同样的逻辑也适用于锚定类型,例如
像feature\u name
,因为
feature\u name
可以与其他类型一起在后代中重新定义