【问题标题】:Providing default value on typesafe config getters为类型安全的配置获取器提供默认值
【发布时间】:2018-09-03 06:22:53
【问题描述】:

所以我的代码中多次出现类似的 sn-ps:

val optionValue = try {
      Some(config.getString(key))
    } catch {
      case _: Missing => None
    }

我想以某种方式从我的代码中消除这些重复项。我知道 typesafe 提供了一种方法来提供回退配置文件以提供默认配置值。但是,就我而言,某些属性没有任何默认值。它们是可选属性。

重构此代码的最佳方式是什么。

【问题讨论】:

    标签: scala refactoring typesafe


    【解决方案1】:

    根据https://github.com/lightbend/config#how-to-handle-defaults,这不是库的工作方式。

    您应该使用withFallback 方法来提供干净的配置。

    【讨论】:

      【解决方案2】:

      由于您使用的是 Scala,并且假设您可以使用implicits,我会推荐使用丰富类的方法,它允许您保留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
      

      docs

      【讨论】:

        【解决方案3】:

        根据 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】:

          config.hasPath('sample.property') 会告诉你属性是否存在。

          【讨论】:

          • 可以发表评论
          【解决方案5】:

          我有类似的问题,这是我的解决方案,希望你喜欢它:

          Try(key).map(config.getString).map(Some(_)).getOrElse(None)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2020-10-07
            • 1970-01-01
            • 2014-04-08
            • 2010-11-09
            • 2019-10-28
            • 2019-01-02
            • 1970-01-01
            相关资源
            最近更新 更多