簡體   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