从属性中读取文件路径,然后读取文件惯用的Scala

时间:2016-09-03 18:27:49

标签: scala

我想从配置中读取文件的路径,然后以惯用的Scala方式读取文件。这是我到目前为止的代码:

val key: Option[String] = {
  val publicKeyPath: Option[String] = conf.getString("bestnet.publicKeyFile")
  publicKeyPath match {
    case Some(path) => {
      Future {
        val source = fromFile(s"./$path")
        val key: String = source.getLines.toIterable.drop(1).dropRight(1).mkString
        source.close()
        key
      } onComplete {
        case Success(key) => Success(key)
        case Failure(t) => None
      }
    }
    case None => None
  }
}

但是,由于我收到错误Expression of type Unit does not conform to Option[String]

,因此无效

我出错了什么,是我的方法惯用Scala还是应该以其他方式完成?

1 个答案:

答案 0 :(得分:0)

如果您想将内容作为String返回,则无需使用Future。例如。以下是:

val key: Option[String] = {
  val publicKeyPath: Option[String] = conf.getString("bestnet.publicKeyFile")
  publicKeyPath match {
    case Some(path) =>
      val source = fromFile(s"./$path")
      val key: String = source.getLines.toIterable.drop(1).dropRight(1).mkString
      source.close()
      Some(key)
    case None =>
      None
  }
}

使用更高级别的函数Some(_)可以更加惯用地转换map的值的模式,即:

val key: Option[String] = {
  val publicKeyPath = conf.getString("bestnet.publicKeyFile")

  publicKeyPath.map(path => {
      val source = fromFile(s"./$path")
      val key = source.getLines.toIterable.drop(1).dropRight(1).mkString
      source.close()
      key
  })
}

进行资源管理(即关闭Source)的更惯用的方法是使用"贷款模式"。例如:

def using[A](r: Resource)(f: Resource => A): A = try {
    f(r)
} finally {
    r.dispose()
}

val key: Option[String] = {
  val publicKeyPath = conf.getString("bestnet.publicKeyFile")

  publicKeyPath.map(path =>
      using(fromFile(s"./$path"))(source =>
          source.getLines.toIterable.drop(1).dropRight(1).mkString
      )
  )
}

Scala是一种灵活的语言,在用户区中定义这样的抽象并不罕见(而在Java中,using抽象是一种语言特性)。

如果您需要非阻止并行代码,则应返回Future[String]而不是Option[String]。这使自动资源管理变得复杂,因为代码在不同的时间执行。无论如何,这应该为您提供改进代码的一些指示。