Eiffel:一旦函数具有通用或锚定结果。尝试创建常量
Eiffel: once function has generic or anchored result. Trying to create constants
我正在尝试创建一些终端日志记录颜色以便能够更清楚地看到我的错误。这样做在我看来很明显我必须创建如下常量。因为我不想每次调用我的常量时都创建一个实例,所以我做这样的事情是有意义的,但是编译器似乎和我的概念不一样...
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
事实上,一旦函数不允许 return 锚定类型或正式泛型类型的值。原因在于 once 函数的语义:无论当前对象类型如何,它的主体只执行一次(我忽略了更复杂的递归情况)。
在您的示例中,可能有 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
因为black
returns like Current
,两个赋值都是有效的:black
的类型在第一次调用时是TERMINAL_COLOR
,TOUCH_PAD_COLOR
- 在第二个。然而,特征black
的主体只执行一次,即在第一次调用时。计算对象的类型是TERMINAL_COLOR
。在第二个赋值中,先前计算的对象被 returned 而没有执行函数的主体 black
。对象的类型仍然是相同的:TERMINAL_COLOR
。但现在此对象已附加到 TOUCH_PAD_COLOR
类型的实体 p
。在 p
上拨打电话,例如p.touch_color
会导致崩溃,因为 class TERMINAL_COLOR
.
中没有方法 touch_color
就术语而言,锚定类型表示根据某些其他实体声明的类型。例如like Current
指的是当前class.
的类型
免责声明。曾经的特征有多种,上面的场景处理的是最常见的情况。
锚类型是当你使用 "like feature" 时(注意你也可以使用 "like {FOO}.bar")。
此外,不要忘记 Once 是 "once per class"(不是按类型)。
这就是为什么 once 函数的结果类型不能使用任何正式泛型的原因。
例如
class FOO [G]
feature
bar: STRING
once
Result := generating_type
end
end
(create {FOO [INTEGER]}).bar
将 return 与 (create {FOO [STRING]}).bar
.
相同的对象
所以,现在如果 bar
会 return G
在 class FOO 中,它会造成麻烦,因为没有办法 return 一个值符合任何形式的(INTEGER、STRING、...)。
这就是为什么泛型被禁止用于一次结果类型的原因。
相同的逻辑适用于 like feature_name
等锚类型,因为 feature_name
可以在后代中与其他类型重新定义。
我正在尝试创建一些终端日志记录颜色以便能够更清楚地看到我的错误。这样做在我看来很明显我必须创建如下常量。因为我不想每次调用我的常量时都创建一个实例,所以我做这样的事情是有意义的,但是编译器似乎和我的概念不一样...
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
事实上,一旦函数不允许 return 锚定类型或正式泛型类型的值。原因在于 once 函数的语义:无论当前对象类型如何,它的主体只执行一次(我忽略了更复杂的递归情况)。
在您的示例中,可能有 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
因为black
returns like Current
,两个赋值都是有效的:black
的类型在第一次调用时是TERMINAL_COLOR
,TOUCH_PAD_COLOR
- 在第二个。然而,特征black
的主体只执行一次,即在第一次调用时。计算对象的类型是TERMINAL_COLOR
。在第二个赋值中,先前计算的对象被 returned 而没有执行函数的主体 black
。对象的类型仍然是相同的:TERMINAL_COLOR
。但现在此对象已附加到 TOUCH_PAD_COLOR
类型的实体 p
。在 p
上拨打电话,例如p.touch_color
会导致崩溃,因为 class TERMINAL_COLOR
.
touch_color
就术语而言,锚定类型表示根据某些其他实体声明的类型。例如like Current
指的是当前class.
免责声明。曾经的特征有多种,上面的场景处理的是最常见的情况。
锚类型是当你使用 "like feature" 时(注意你也可以使用 "like {FOO}.bar")。
此外,不要忘记 Once 是 "once per class"(不是按类型)。 这就是为什么 once 函数的结果类型不能使用任何正式泛型的原因。 例如
class FOO [G]
feature
bar: STRING
once
Result := generating_type
end
end
(create {FOO [INTEGER]}).bar
将 return 与 (create {FOO [STRING]}).bar
.
所以,现在如果 bar
会 return G
在 class FOO 中,它会造成麻烦,因为没有办法 return 一个值符合任何形式的(INTEGER、STRING、...)。
这就是为什么泛型被禁止用于一次结果类型的原因。
相同的逻辑适用于 like feature_name
等锚类型,因为 feature_name
可以在后代中与其他类型重新定义。