2011-12-25 27 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是人们真正使用这些天的唯一实现,虽然...