【问题标题】:Scala object constructorScala 对象构造函数
【发布时间】:2019-01-30 09:41:15
【问题描述】:

我必须创建一个文件加载器对象,并且我希望在创建对象时只加载一次文件。
到目前为止,我所做的是使用 read 方法创建一个特征,该方法将读取文件并输出字符串列表。

trait Loader {
  protected val readSource: List[String] = {
    Source
      .fromInputStream(getClass.getResourceAsStream("filename"), "UTF-8")
      .getLines()
      .toList
  }

  def transform(delimeter: String): Vector[C] = {
    val lines = readSource
    // process the lines
  }
}

trait由多个对象实现,在客户端代码中可以多次调用transform方法。

我想避免每次调用 transform 方法时都重新读取文件,我的第一个解决方案是从 transform 方法中提取 val lines = readSource 并将其作为函数 def loadFile = readSource 并在我的对象像这样调用 loadFile :

object MyLoader extends Loader {
  def apply: List[String] = {
    loadFile
  }
}

我想知道这是否是正确的方法。谢谢你的建议。

【问题讨论】:

  • 尽管有名字,readSource不是一个方法,它只是一个val,在创建对象时初始化一次,所以每次调用transform时都不会读取文件.但是我会将其设为lazy val,以便在第一次使用它之前不会对其进行初始化,这将在对象初始化之后。

标签: scala


【解决方案1】:

如果您希望资源读取一次,那么您应该在单例对象中执行此操作,该对象将延迟初始化一次。

客户端应该使用该对象。 “优先组合胜于继承”是口头禅。

如果你想要一个让对象易于使用的混入,你可以使用“self-types”来约束客户端:

trait HasResource { val resource: R = TheResource }
trait Client { self: HasResource => def getR: R = resource }

这是使东西可用的“蛋糕模式”方式。

【讨论】:

    猜你喜欢
    • 2016-04-11
    • 2013-10-20
    • 2021-10-22
    • 1970-01-01
    • 2014-03-25
    • 1970-01-01
    • 2013-09-08
    • 2011-02-11
    • 1970-01-01
    相关资源
    最近更新 更多