decline库中如何用for-comprehension构建Opts配置?
在decline配置/命令行库中使用for-comprehension的可行性
当配置对应的case class成员较多时,使用Opts类的mapN方法生成配置的代码会变得难以阅读且容易出错。我想改用for-comprehension来实现,比如这样:
val databaseConfig: Opts[DatabaseConfig] = { for { username <- Opts.envWithDefault[String]("POSTGRES_USER", "Postgres username", "postgres") password <- Opts.envWithDefault[String]("POSTGRES_PASSWORD", "Postgres password", "postgres") hostname <- Opts.envWithDefault[String]("POSTGRES_HOSTNAME", "Postgres hostname", "localhost") database <- Opts.envWithDefault[String]("POSTGRES_DATABASE", "Postgres database", "thebean") port <- Opts.envWithDefault[Int]("POSTGRES_PORT", "Postgres port", 5432) threadPoolSize <- Opts.envWithDefault[Int]("POSTGRES_THREAD_POOL_SIZE", "Postgres thread pool size", 4) } yield DatabaseConfig(username, password, hostname, database, port, threadPoolSize) }
但这段代码无法运行,因为Opts并没有定义flatMap方法,我也找不到合适的实现方式。想请教有没有解决方案?是不是我遗漏了必要的导入?
补充说明
我当前使用mapN的代码(实际项目中case class成员更多)是这样的:
( Opts.envWithDefault[String]("POSTGRES_USER", "Postgres username", "postgres"), Opts.envWithDefault[String]("POSTGRES_PASSWORD", "Postgres password", "postgres"), Opts.envWithDefault[String]("POSTGRES_HOSTNAME", "Postgres hostname", "localhost"), Opts.envWithDefault[String]("POSTGRES_DATABASE", "Postgres database", "thebean"), Opts.envWithDefault[Int]("POSTGRES_PORT", "Postgres port", 5432), Opts.envWithDefault[Int]("POSTGRES_THREAD_POOL_SIZE", "Postgres thread pool size", 4) ).mapN(DatabaseConfig.apply)
这种写法在成员多的时候,要查看某个参数对应的环境变量得逐个计数,体验很差。
有评论建议先单独定义每个Opts变量再调用mapN,代码如下:
val username = Opts.envWithDefault[String]("POSTGRES_USER", "Postgres username", "postgres") val password = Opts.envWithDefault[String]("POSTGRES_PASSWORD", "Postgres password", "postgres") val hostname = Opts.envWithDefault[String]("POSTGRES_HOSTNAME", "Postgres hostname", "localhost") val database = Opts.envWithDefault[String]("POSTGRES_DATABASE", "Postgres database", "thebean") val port = Opts.envWithDefault[Int]("POSTGRES_PORT", "Postgres port", 5432) val threadPoolSize = Opts.envWithDefault[Int]("POSTGRES_THREAD_POOL_SIZE", "Postgres thread pool size", 4) (username, password, hostname, database, port, threadPoolSize).mapN(DatabaseConfig.apply)
但这不正是for-comprehension的适用场景吗?用for-comprehension写会更简洁直观,所以我想知道是不是漏了什么导入,或者decline库刻意禁止对Opts执行flatMap操作?
内容的提问来源于stack exchange,提问作者csjacobs24
相关产品推荐
相关产品推荐

