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

Wil*_*ken 12 swift

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

var networkManager = NetworkManager.sharedInstance()

var lazy networkManager = NetworkManager.sharedInstance()

都:

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

懒:

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

不懒:

  • 没有任何好处

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

(我不是在询问var和let la la之间的区别是默认的Swift常量是懒惰的吗?)

lee*_*eor 9

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

虽然这属于Clojure的,这个博客帖子由Stuart塞拉利昂解释了这个想法非常好,我认为它在任何语言也同样适用.


Luc*_*tti 7

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

这是与游戏开发相关的一个例子(以及许多其他).

通常,在级别开始之前创建表示游戏场景/级别中的项目的类的实例.

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

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


Rob*_*ier 5

仅供参考.我的感觉是,Swift希望变得更像一种功能语言,并希望在更多地方进行懒惰的实例化.

我对Swift的早期评估随着时间的推移而保持良好状态(好吧,"非功能性"部分.我没想到Swift会在以后的版本中使用多少方法而不是函数).Swift不是一种功能语言,也不打算成为一种语言.这经常出现在WWDC会谈,论坛,推特以及与Swift团队的对话中.最初所有的地图和过滤器都是懒惰的.Swift删除了它,因为它引起的问题.关于该主题的最佳讨论可能是"在Swift中使用价值类型构建更好的应用程序".正如他们所说:

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

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

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

但是,对于手头的问题:

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

正如您可能知道的那样,默认情况下,全局变量和类变量都是惰性的,而且我认为它们的效果非常好,因为它们的数量要少得多,在实践中它们更难以被访问,并且懒惰是线程安全的(有成本,但由于它们非常罕见,成本要低得多).