提问者:小点点

Swift:为什么默认情况下所有变量都不是惰性的?


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

var networkManager=NetworkManager. share dInstance()

var惰性networkManager=NetworkManager. share dInstance()

两者:

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

懒惰:

  • 可以指self
  • 直到需要时才计算
  • 如果你不使用它,它永远不会被计算

不懒:

  • 没有任何好处

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

(我不是在问var和letàla之间的区别Swift常量默认情况下是惰性的吗?)


共3个答案

匿名用户

一个原因可能是懒惰不适合你想要控制的情况,当评估发生时。这与作业中完成的工作有副作用的情况有关。

虽然这与结束有关,但stuart siSierra的这篇博客文章很好地解释了这个想法,我认为它在任何语言中都同样适用。

匿名用户

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

这是一个与游戏开发相关的例子。

通常,代表游戏场景/关卡中物品的类实例是在关卡开始之前创建的。

初始化可能是一项耗时的任务(从持久存储中加载内容、分配内存、准备实例…),在玩家开始玩关卡之前完成这一部分确实避免了CPU开销。

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

匿名用户

FYI我的感觉是,Swift希望变得更像一种函数式语言,希望在更多的地方实现惰性实例化。

随着时间的推移,我对Swift的早期评估得到了很好的支持(嗯,“非功能性”部分。我没有预料到Swift在以后的版本中会在多大程度上偏爱方法而不是函数)。Swift不是一门功能性语言,也不打算成为一门功能性语言。这在WWDC的演讲、论坛、Twitter以及与Swift团队的对话中经常出现。最初,所有的地图和过滤器都是懒惰的。Swift删除了它,因为它造成了问题。关于这个主题,最好的演讲可能是“在Swift中使用值类型构建更好的应用程序”。正如他们所说:

我们喜欢突变。我们认为它很有价值。我们认为如果做得正确,它很容易使用。

没有比这更“非功能性”的了。Swift也包含不可变数据。但是函数式编程是关于不可变数据上的纯函数,这不是Swift。

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

不过,对于手头的问题:

我发现惰性属性在现实世界的Swift中很少有用(我很慷慨;我从未遇到过将其保留在代码中的情况)。它不像Haskell中那样提供任何惰性。它不是线程安全的,所以这是一场噩梦。它迫使你使用引用类型(或强制你的结构可变),所以这可能很烦人。如果我听说他们从语言中删除了它,我们只需要滚动我们自己的结构,那对我来说没问题。(我很想写一个建议来做到这一点。)它实现了一个特定的备忘录模式,偶尔会很方便,但通常不是你想要的。所以这不是违约是一件非常好的事情。

你可能知道,默认情况下,全局变量和类变量是惰性的,我认为这往往会很好地解决,因为它们的数量少得多,在实践中它们不会被访问的机会要大得多,而且惰性是线程安全的(这是有代价的,但是因为它们少得多,所以成本要低得多)。

相关问题