[英]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_object
是if塊的本地變量,它指向與some_object
相同的對象,但靜態保證是非void。
但是,我沒有看到這個as-clause存在的原因。 正如我在上面指出的那樣,顯然原來的some_object
已經在if-block中靜態保證是非空的,那么引入另一個變量又有什么意義呢?
除范圍外, some_object
和l_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是只讀的,不受任何中間功能調用或其他線程對同一表達式的評估的影響。 換句話說,它始終是附加的。
在某些情況下,對象測試表達式不受這些因素的影響:
參數是只讀的,因此使用簡短形式總是足夠的
attached arg
引入對象測試局部是沒有意義的,因為它總是等於參數。
如果為局部變量和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.