Swift:为什么默认情况下并非所有变量都是懒惰的?

时间:2016-01-17 18:21:11

标签: swift

比较这两个用于定义实例属性的选项:

  

var networkManager = NetworkManager.sharedInstance()

     

var lazy networkManager = NetworkManager.sharedInstance()

这两种:

  • 可以评估一个块以获取值
  • 可以内联声明(不是块,如上所述)

懒:

  • 可以参考自我
  • 直到需要才计算
  • 如果您不使用它,则永远不会计算

非懒:

  • 没有任何好处

似乎使用非惰性变量没有任何好处。那么为什么语言允许程序员做出这种低劣的选择呢?

(我不是在询问var和let la la Are Swift constants lazy by default?之间的区别)

5 个答案:

答案 0 :(得分:9)

一个原因可能是懒惰不适合在评估发生时需要控制的情况。这与在任务中完成的工作有副作用的情况相关。

虽然这与clojure有关,但stuart sierra的这篇博客post很好地解释了这个想法,我认为它同样适用于任何语言。

答案 1 :(得分:7)

正如其他人已经说过的,有几个关键场景,你希望属性的初始化是确定性的

这是与游戏开发相关的一个示例(与众不同)。

通常,代表游戏场景/关卡中的项目的类的实例是在<+>之前创建的。

初始化可能是一项耗时的任务(从持久存储中加载内容,分配内存,准备实例......)并且在播放器开始播放级别之前执行此部分确实可以避免 CPU开销

这很关键,因为在一个级别中间的CPU开销可能会导致帧速率下降,这对用户体验来说是一场噩梦。

答案 2 :(得分:5)

  

FYI。我的感觉是,Swift希望变得更像一种功能性语言,并希望在更多地方进行懒惰的实例化。

随着时间的推移,

My early assessment of Swift已经相当不错了(好吧,“非功能性”部分。我没想到Swift会在以后的版本中使用多少方法而不是函数)。 Swift不是一种功能语言,也不打算成为一种语言。这经常出现在WWDC会谈,论坛,推特以及与Swift团队的对话中。最初所有的地图和过滤器都是懒惰的。 Swift删除了它,因为它引起的问题。可能关于该主题的最佳谈话是"Building Better Apps with Value Types in Swift"。正如他们所说:

  

我们喜欢变异。我们认为它很有价值。我们认为正确完成后很容易使用。

你没有比这更“无功能”。 Swift还拥抱不可变数据。但函数式编程是关于不可变数据的纯函数,而不是Swift。

(当然有很多非懒惰的函数式语言。懒惰和功能都是正交概念.Haskell碰巧接受了两者。)

对于手头的问题,但是:

我发现lazy属性在现实世界的Swift中很少有用(我很慷慨;我从未遇到过我将其保存在代码中的情况)。它没有提供像你在Haskell中得到的懒惰。 It isn't thread safe,所以这是一场噩梦。它强迫你进入引用类型(或强制你的结构是可变的),这样可能很烦人。如果我听说他们是从语言中拉出来的话我们只是不得不自己动手,那对我来说没关系。 (我很想写一个提案来做到这一点。)它实现了一个特定的备忘录模式,偶尔可以派上用场,但往往不是你想要的。所以它不是默认值,这是一件非常好的事情。

正如您可能知道的那样,默认情况下,全局变量和类变量 是懒惰的,而且我认为这种方法很容易解决,因为它们的数量要少得多,因此它们的可能性要大得多在实践中不会被访问,并且懒惰是线程安全的(这有成本,但因为它们非常罕见,所以成本要低得多)。

答案 3 :(得分:0)

如果您有一个昂贵的对象(就创建而言需要很长时间),您可以决定并控制何时创建它。有人可能会认为懒惰变量应该是默认变量。也许它有历史原因。 ObjC中的惰性属性产生了很多样板代码。

答案 4 :(得分:0)

lazy var不是线程安全的。您可以使用dispatch_once,常数(let)或嵌套结构模式(通常用于单例)来确保线程安全。您也可以使用NSRecursiveLock来使用自己的锁定,但是效率可能不如dispatch_once

似乎并非所有lazy变量都保证在多线程环境中被初始化一次。您需要对其进行显式编程,或者使用静态属性。

  

尽管延迟加载可以帮助开发人员减少内存占用,   避免将太多数据加载到内存中,甚至避免工作   某种初始化或设置问题(例如设置视图)   当您需要访问自己而不是自己的实例时   初始化)。但是,并不总是应用延迟加载   免费电话:有时您需要加倍努力以避免   副作用。最后,不要害怕延迟变量。它仍然是   可以帮助您实现其存在的奇妙事物。   干杯!