所以我的代码中多次出现类似的片段:
val optionValue = try {
Some(config.getString(key))
} catch {
case _: Missing => None
}
我想以某种方式从我的代码中消除此重复项。我知道typesafe提供了一种方法来提供备用配置文件以提供默认配置值。但是,就我而言,我没有某些属性的任何默认值。它们是可选属性。
重构此代码的最佳方法是什么。
答案 0 :(得分:0)
由于您使用的是Scala,并且假定您可以使用隐式,所以我建议使用一种使用丰富类的推荐方法,该类可以使您保留Option
语法。
示例配置。
existent.sample.string="I exist!"
existent.sample.boolean=true
浓缩课程示例。
package config
import com.typesafe.config.{Config, ConfigException}
object MyConfig {
implicit class RichConfig(val config: Config) extends AnyVal {
def optionalString(path: String): Option[String] = if (config.hasPath(path)) {
Some(config.getString(path))
} else {
None
}
def optionalBoolean(path: String): Option[Boolean] = if (config.hasPath(path)) {
Some(config.getBoolean(path))
} else {
None
}
// An example of using the exception approach - but less efficient than using hasPath
def optionalString2(key: String): Option[String] = try {
Some(config.getString(key))
} catch {
case _: ConfigException => None
}
}
}
请注意,最好使用hasPath
(而不是使用Try
)来检查您的方案中是否存在密钥,而不是让JVM创建一个异常,该异常对于可选项是不感兴趣的配置。允许不存在。
演示。
import com.typesafe.config._
object ConfigTest extends App {
import MyConfig._
val conf = ConfigFactory.load
val optionalString = conf.optionalString("existent.sample.string")
val optionalStringNone = conf.optionalString("non-existent.sample.string")
println(s"String config value: $optionalString")
println(s"Optional (non-existent) String config value: $optionalStringNone")
val optionalBoolean = conf.optionalBoolean("existent.sample.boolean")
val optionalBooleanNone = conf.optionalBoolean("non-existent.sample.boolean")
println(s"Boolean config value: $optionalBoolean")
println(s"Optional (non-existent) String config value: $optionalBooleanNone")
}
打印。
// String config value: Some(I exist!)
// Optional (non-existent) String config value: None
// Boolean config value: Some(true)
// Optional (non-existent) String config value: None
答案 1 :(得分:0)
根据https://github.com/lightbend/config#how-to-handle-defaults,这不是库的工作方式。
您应该使用withFallback
方法来提供干净的配置。
答案 2 :(得分:0)
config.hasPath('sample.property')会告诉您该属性是否存在。
答案 3 :(得分:0)
根据Jacko的回答,我希望简化代码,避免为每种类型复制和粘贴hasPath
方法。
implicit class RichConfig(val config: Config) extends AnyVal {
private def getOptional[T](path: String, get: String => T): Option[T] = {
if (config.hasPath(path)) {
Some(get(path))
} else {
None
}
}
def optionalString(path: String): Option[String] = getOptional(path, config.getString)
def optionalInt(path: String): Option[Int] = getOptional(path, config.getInt)
def optionalDouble(path: String): Option[Double] = getOptional(path, config.getDouble)
def optionalBoolean(path: String): Option[Boolean] = getOptional(path, config.getBoolean)
}
答案 4 :(得分:0)
我有类似的问题,这是我的解决方案,希望您喜欢:
Try(key).map(config.getString).map(Some(_)).getOrElse(None)