我想从配置中读取文件的路径,然后以惯用的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还是应该以其他方式完成?
答案 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]
。这使自动资源管理变得复杂,因为代码在不同的时间执行。无论如何,这应该为您提供改进代码的一些指示。