【问题标题】:Eiffel: best way to create a redefinable "constant"埃菲尔:创建可重新定义的“常数”的最佳方式
【发布时间】:2019-08-22 15:53:44
【问题描述】:

正如this question 中提到的,没有办法定义一个我可以重新定义为后代的常量。

在我的许多情况下,我都希望有一个可以重新定义的常量。我认为避免在每次咨询中创建的替代方案是没有意义的

这是不可行的

class A

feature -- Access

    Default_value: STRING = "some A value"

end -- Class


class B

inherit
    B
        redefine
            Default_value
        end

feature -- Access

    Default_value: STRING = "some B value"

end -- Class

使用一次 instance_free 替代

class A

feature -- Access

    Default_value: STRING
        once
            Result := "some A value"
        ensure
            instance_free: class
        end

end -- Class


class B

inherit
    B
        redefine
            Default_value
        end

feature -- Access

    Default_value: STRING
        once
            Result := "some B value"
        ensure
            instance_free: class
        end

end -- Class

据我了解,一次不会使用 B 值创建,因为将采用 A 类值

带属性的替代方案

class A

feature -- Access

    Default_value: STRING
        attribute
            Result := "some A value"
        ensure
            instance_free: class
        end

end -- Class


class B

inherit
    B
        redefine
            Default_value
        end

feature -- Access

    Default_value: STRING
        attribute
            Result := "some B value"
        ensure
            instance_free: class
        end

end -- Class

这是唯一的好习惯吗?

【问题讨论】:

    标签: eiffel


    【解决方案1】:

    在提到的 3 种可能性中,只有一次无实例函数可以使用,因为

    • 常量被冻结,因此无法重新定义;
    • 不支持无实例属性。

    另一种方法是使用带有 manifest once 字符串的常规函数​​来保证结果始终相同:

    class A feature
        default_value: STRING
            do
                Result := once "some A value" -- Note the modifier "once".
            ensure
                instance_free: class
                constant: Result = default_value -- Ensure the Result is constant.
            end
    end
    

    但是,与无实例的 once 函数相比,似乎没有什么特别的好处。 (我仍然会保留后置条件 constant 以避免错误地重新声明该功能。)

    编辑。上面示例的一些细节:

    1. 在运行时,"foo" 形式的常规清单字符串在每次评估时都会创建一个新的字符串对象。一旦once "foo" 形式的清单字符串仅在第一次创建一个新的字符串对象。在随后的评估中,它们生成与之前计算的相同的对象。

    2. 查询f 的后置条件Result = f(该示例使用default_value 而不是f)确保对f 的第二次调用产生与第一次调用相同的对象。实际上,在表达式Result = f 中,Result 指的是由特征计算的对象。调用f 指的是第二次调用该功能计算的对象。因此,每当我们调用f 时,它都会生成相同的对象。 (理想情况下,我们会明确要求对该功能的第三次、第四次等调用也产生相同的对象。但是,这超出了语言的表达能力。形式上,f 产生的所有结果的相等性可以是通过归纳证明。)

    【讨论】:

    • Thx,我被困在一次“内联”和Result = default_value 的语义上(对我来说似乎很明显,可能是什么情况不真实?)你能告诉更多关于这 2 个新概念是给我的还是给我指出一些关于它的文档?
    • @Pipo 我已经为答案添加了解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多