深入解析ajalt/clikt库中的选项功能
什么是Clikt选项
在ajalt/clikt命令行解析库中,选项(Options)是命令行工具中常见的参数形式,通常以--
或-
开头。Clikt通过属性委托的方式定义选项,使得开发者可以轻松地为命令添加各种类型的选项参数。
基础选项使用
最简单的选项定义方式如下:
class Hello: CliktCommand() {
val name by option(help="你的名字")
override fun run() {
echo("你好, $name!")
}
}
这种基础选项:
- 默认接受一个String类型的值
- 属性可为空(nullable)
- 如果命令行未提供该选项,属性值为null
- 如果多次提供该选项,取最后一次出现的值
选项命名规则
Clikt提供了灵活的选项命名机制:
-
自动推断命名:如果不指定名称,Clikt会根据属性名自动生成小写连字符格式的名称。例如
val myOpt by option()
会自动生成--my-opt
选项。 -
手动指定名称:可以显式指定任意数量的名称:
val name by option("-n", "--name", help="你的名字")
命名规则差异:
- 两个字符的名称(如
-n
)被视为POSIX风格的短选项- 使用方式:
-nfoo
或-n foo
- 使用方式:
- 其他长度的名称被视为长选项
- 使用方式:
--name=foo
或--name foo
- 使用方式:
选项的三大自定义维度
Clikt选项支持三个维度的独立定制:
- 值类型转换:默认String类型,可通过
int()
,choice()
等函数转换 - 值数量控制:默认单个值,可通过
pair()
,triple()
等扩展 - 处理逻辑:默认取最后一次出现的值,可通过
default()
,multiple()
等改变
这种正交设计使得各种定制可以自由组合。
默认值设置
默认情况下,未提供的选项返回null。可以通过default()
设置默认值:
val exp by option("-e", "--exp").double().default(1.0)
对于计算成本高的默认值,可以使用defaultLazy
延迟计算:
val config by option().defaultLazy { computeExpensiveDefault() }
多值选项处理
Clikt支持多种多值选项形式:
固定数量值
内置pair()
和triple()
处理2-3个值,更多值可使用transformValues
:
data class Quad(val a: Int, val b: Int, val c: Int, val d: Int)
val tesseract by option().int().transformValues(4) {
Quad(it[0], it[1], it[2], it[3])
}
分隔符分割值
使用split()
按分隔符分割值:
val profiles by option("-P").split(",")
可变数量值
使用varargValues()
处理空格分隔的多个值:
val sizes: List<String> by option().varargValues()
多选项收集
默认取最后一次出现的值,使用multiple()
可收集所有值:
val message: List<String> by option("-m").multiple()
可结合去重使用:
val platforms: Set<String> by option("-p").multiple().unique()
键值对与Map选项
使用splitPair()
处理键值对,associate()
收集多个键值对到Map:
val systemProp: Map<String, String> by option("-D").associate()
布尔标志选项
无值的布尔标志选项:
val flag by option("--on").flag("--off", default=false)
短标志可合并使用:
./cli -abfFoo # 同时设置-a和-b标志
计数标志选项
使用counted()
统计选项出现次数:
val verbosity by option("-v").counted(limit=3, clamp=true)
功能开关标志
使用switch()
为不同标志名分配不同值:
val size by option().switch(
"--large" to "大号",
"--small" to "小号"
).default("未知")
选择限制选项
使用choice()
限制可选值范围:
val hash by option().choice("md5", "sha1")
互斥选项组
使用mutuallyExclusiveOptions
创建互斥选项:
val fruit: Fruit? by mutuallyExclusiveOptions<Fruit>(
option("--apples").convert { Apples(it.toInt()) },
option("--oranges").convert { Oranges(it) }
)
协同出现选项组
使用cooccurring()
确保选项必须同时出现:
class UserOptions : OptionGroup() {
val name by option().required()
val age by option().int()
}
val userOptions by UserOptions().cooccurring()
通过以上功能,Clikt提供了强大而灵活的命令行选项处理能力,可以满足各种复杂的命令行参数需求。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考