2011-12-25 39 views
10

我已經注意到這個成語在Data.Unique`unsafePerformIO(newTVarIO 0)`安全嗎?

uniqSource :: TVar Integer 
uniqSource = unsafePerformIO (newTVarIO 0) 
{-# NOINLINE uniqSource #-} 

是它保證只運行一次?

+0

作爲一般的經驗法則,'unsafePerformIO'應該只用作庫代碼的實現細節,然後你應該只使用它,因爲你是相當肯定,絕對沒有其他方法可以實現相同的性能/行爲。我不完全確定爲什麼我覺得有必要在這裏說,因爲它與問題不是100%密切相關,但是你去了。 – 2011-12-26 05:29:55

+0

相關:http://stackoverflow.com/questions/6076129/ – fuz 2011-12-26 14:14:00

回答

11

在GHC中,是的。 有關更多信息,請參見the documentation;有一個可以多次執行的變體unsafeDupablePerformIO,避免了致力於實現這種保證的開銷。

請注意,unsafePerformIO創建可變變量通常是不安全的;如文檔中所述,您可以創建多態引用並使用它來實現unsafeCoerce。儘管這不是你可能意外做的事,但它不適用於有問題的代碼(因爲引用的類型是明確指定的)。

safe-globals軟件包以一種確保安全的方式提取此「成語」(雖然在某些情況下有用,但它是generally considered an antipattern,不應在正常代碼中使用)。

另請參閱我的previous answer關於unsafePerformIO以及在應用時必須注意的事項。

我很確定它也適用於所有其他實現; GHC爲避免重複執行而採取的特殊處理措施僅在線程化設置中非常必要,而且我不知道Haskell的任何其他線程化實現。 GHC是人們真正使用這些天的唯一實現,雖然...