我已經注意到這個成語在Data.Unique:`unsafePerformIO(newTVarIO 0)`安全嗎?
uniqSource :: TVar Integer
uniqSource = unsafePerformIO (newTVarIO 0)
{-# NOINLINE uniqSource #-}
是它保證只運行一次?
我已經注意到這個成語在Data.Unique:`unsafePerformIO(newTVarIO 0)`安全嗎?
uniqSource :: TVar Integer
uniqSource = unsafePerformIO (newTVarIO 0)
{-# NOINLINE uniqSource #-}
是它保證只運行一次?
在GHC中,是的。 有關更多信息,請參見the documentation;有一個可以多次執行的變體unsafeDupablePerformIO
,避免了致力於實現這種保證的開銷。
請注意,unsafePerformIO
創建可變變量通常是不安全的;如文檔中所述,您可以創建多態引用並使用它來實現unsafeCoerce
。儘管這不是你可能意外做的事,但它不適用於有問題的代碼(因爲引用的類型是明確指定的)。
safe-globals軟件包以一種確保安全的方式提取此「成語」(雖然在某些情況下有用,但它是generally considered an antipattern,不應在正常代碼中使用)。
另請參閱我的previous answer關於unsafePerformIO
以及在應用時必須注意的事項。
我很確定它也適用於所有其他實現; GHC爲避免重複執行而採取的特殊處理措施僅在線程化設置中非常必要,而且我不知道Haskell的任何其他線程化實現。 GHC是人們真正使用這些天的唯一實現,雖然...
作爲一般的經驗法則,'unsafePerformIO'應該只用作庫代碼的實現細節,然後你應該只使用它,因爲你是相當肯定,絕對沒有其他方法可以實現相同的性能/行爲。我不完全確定爲什麼我覺得有必要在這裏說,因爲它與問題不是100%密切相關,但是你去了。 – 2011-12-26 05:29:55
相關:http://stackoverflow.com/questions/6076129/ – fuz 2011-12-26 14:14:00