替代在构造函数中执行大量计算 – scala
我正在学习一个新项目的
scala,尽可能地追求不变性和功能风格.
我正在创建的对象之一在其构造函数中接受了大量输入,然后重复应用大量计算来生成相关输出,这些输出作为字段存储在对象上. 在执行计算并将其结果内部添加到可变ListBuffer时,关于该对象的所有其他内容都是不可变的 – 一旦创建,您就无法更改任何输入值并再次运行计算显然会产生相同的结果. 但是,在构造函数中进行如此多的计算似乎并不合适.我能看到的唯一方法是将计算值设置为变量并提供执行计算的run方法 – 但是这个方法可以被多次调用,这是毫无意义的. 在scala构造函数中做很多事情真的很好吗?例如,没有对DB的调用,只是内部计算.或者有一些模式吗? 这是非常简单形式的基本思想: class Foo(val x:Int,val y:Int,calculations:List[Calculation]) { val xHistory = new collection.mutable.ListBuffer[Int]() val yHistory = new collection.mutable.ListBuffer[Int]() calculations.map { calc => calc.perform(this) }.foreach { result => xHistory += result.x yHistory += result.y } } 基本上我希望输入包装在一个方便的Foo对象实例中,这样我就可以将它传递给各种计算策略(每个计算策略可能需要不同的输入组合). 解决方法
在构造函数内部工作
通常我在构造函数中做昂贵的东西.但请注意,评论中提到构造函数代码可能不太优化(在此处插入Java实现,这是正确的).如果您有多线程应用程序,也请阅读下一段. 延迟初始化 我不知道在构造函数中做大量工作可能有什么问题. 正如评论中所指出的,构造函数内部运行的代码可能存在问题.因此,Scala 2.8.0中引入了DelayedInit特性.例如,在使用Swing GUI元素时会出现此类问题.
懒惰的构造 要以不同的方式延迟计算,可以使用以下方法,这也解决了并发问题: >您可以使用lazy val成员,这些成员将在首次请求时进行计算. 指示使用懒惰 您可能想要做的另一个考虑因素是计算值是否会被使用.如果可能不需要它们,那么使用我描述的惰性方法就是要走的路.另一方面,如果你肯定访问这些昂贵的成员,我认为在构造函数中进行计算没有任何问题,并且使用惰性成员可能会增加不必要的计算开销. 关于OP示例的注释 在构造函数中做危险的事情并不好;比如让对部分构造的对象的引用转义构造函数(通过this-reference). OP中的示例使用calc.perform(this)执行此操作.以下建议无法修复此“潜在错误”. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |