You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 17:50:36