繁体   English   中英

埃菲尔附加声明中的局部变量有什么意义?

[英]What's the point of the local variable in Eiffel's attached-statement?

在Eiffel中,Void Safety是一种静态防止取消引用未初始化(“null”)对象的方法。 它的工作方式是,首先,必须将对象声明为可拆卸 ,然后您需要在使用它之前检入if-block是否实际附加了对象(即具有某些值)。

这是我到目前为止使用它的方式:

some_object: detachable TYPE

...

if attached some_object then
  some_object.method
end

工作完全正常:没有附加检查,编译失败,“Object_call的目标可能无效”错误。 但是,在实际阅读有关Void Safety的文档之后,我了解到这实际上是这样的:

some_object: detachable TYPE

...

if attached some_object as l_some_object then
  l_some_object.method
end

在这种形式中, l_some_objectif块的本地变量它指向与some_object相同的对象,但静态保证是非void。

但是,我没有看到这个as-clause存在的原因。 正如我在上面指出的那样,显然原来的some_object已经在if-block中静态保证是非空的,那么引入另一个变量又有什么意义呢?

除范围外, some_objectl_some_object之间有什么区别?

简短的回答

如果some_object是局部变量,则没有必要引入对象测试本地l_some_object

答案很长

对象测试的一般形式是

attached {SOME_TYPE} expr as var

其中{SOME_TYPE}var是可选的。 如果未使用类型(上例中的{SOME_TYPE} ),则对象测试仅检查是否附加了expr并在附加时将其值赋给var

从理论上讲,以下内容可能是无效的:

if attached expr then
    expr.do_something
end

但是在一般情况下不允许这样做,因为expr可能有副作用,因此第二次计算它时,会返回一个不同的值,并且此值可能void使得代码void-unsafe:

if attached foo then -- On first call function foo returns non-void value.
    foo.do_something -- On second call function foo returns void: BOOM!
end

另一种可能性是改变表达式值的中间调用,例如,

if attached attr then -- Attribute attr is attached here.
    bar               -- bar sets attr to Void.
    attr.do_something -- BOOM!
end

如果bar将属性attr设置为void (这可以间接完成),则代码再次为void-unsafe。

最后,在多线程环境中,另一个线程可能会在检查之后以及在“then”部分内部使用之前更改attr的值,即使没有任何中间功能调用:

if attached attr then -- Attribute attr is attached here.
                      -- Another thread sets attr to Void.
    attr.do_something -- BOOM!
end

为了防止这些情况,使用var部分。 此对象测试local是只读的,不受任何中间功能调用或其他线程对同一表达式的评估的影响。 换句话说,它始终是附加的。

在某些情况下,对象测试表达式不受这些因素的影响:

  1. 参数是只读的,因此使用简短形式总是足够的

     attached arg 

    引入对象测试局部是没有意义的,因为它总是等于参数。

  2. 如果为局部变量和Result分配了可分离的表达式,则它们可能只会变为Void 如果没有这样的任务,同样的

     attached local_var 

    很好。 但是,只要为本地分配了可分离的表达式,就不再将其视为附加:

     if attached local_var then ... -- OK to use local_var as attached. local_var := detachable_expression ... -- No guarantees about local_var attachment status. end 

    如果不希望出现这种情况,可以使用长形式的对象测试

     attached local_var as attached_local_var 

    它保证了attached_local_var始终附加。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM