Kotlin 的函数式主函数参数解析

Gen*_*hen 6 parameter-passing kotlin

如果我这样写问答不合适,请告诉我。另外,我也期待更好的答案。我提供的两种解决方案都不是完美的。

现在网上有一些 Kotlin 参数解析器,例如GitHub:xenomachina/kotlin-argparserGitHub:Kotlin/kotlinx.cliGitHub:ajalt/clikt。但是我不想将这么大的文件夹添加到我的(也许)小项目中。我想要的是一个简单而干净的解决方案,例如只是一个函数,具有“流畅”的流式实现。相反,这些项目都包含多个文件。

我的想法是,只需要将命令行参数解析为 a Map<String, List<String>>,使用map.containsKey()来获取no_argument参数,然后使用map[key]来获取required_argument参数。

例如,命令行参数列表

-a -b c -d e f g -h --ignore --join k --link m n o -p "q r s"
Run Code Online (Sandbox Code Playgroud)

将被解析为:

{-a=[], -b=[c], -d=[e, f, g], -h=[], --ignore=[], --join=[k], --link=[m, n, o], -p=[q r s]}
Run Code Online (Sandbox Code Playgroud)

或者我们说

mapOf(
    "-a" to listOf(), // POSIX style, no argument
    "-b" to listOf("c"), // POSIX style, with single argument
    "-d" to listOf("e", "f", "g"), // POSIX style, with multiple argument
    "-h" to listOf(), // POSIX style, no argument
    "--ignore" to listOf(), // GNU style, no argument
    "--join" to listOf("k"), // GNU style, with single argument
    "--link" to listOf("m", "n", "o"), // GNU style, with multiple argument
    "-p" to listOf("q r s") // POSIX style, with single argument containing whitespaces
)
Run Code Online (Sandbox Code Playgroud)

Oma*_*gra 7

last嗯,我的解决方案还涉及不变性和参数折叠。

fun main(args: Array<String>) {
    val map = args.fold(Pair(emptyMap<String, List<String>>(), "")) { (map, lastKey), elem ->
        if (elem.startsWith("-"))  Pair(map + (elem to emptyList()), elem)
        else Pair(map + (lastKey to map.getOrDefault(lastKey, emptyList()) + elem), lastKey)
    }.first

    println(map)

    val expected = mapOf(
        "-a" to emptyList(),
        "-b" to listOf("c"),
        "-d" to listOf("e", "f", "g"),
        "-h" to emptyList(),
        "--ignore" to emptyList(),
        "--join" to listOf("k"),
        "--link" to listOf("m", "n", "o"),
        "-p" to listOf("q r s"))

    check(map == expected)
}
Run Code Online (Sandbox Code Playgroud)

输出

{-a=[], -b=[c], -d=[e, f, g], -h=[], --ignore=[], --join=[k], --link=[m, n, o], -p=[q r s]}
Run Code Online (Sandbox Code Playgroud)

它还处理第一个参数是参数的情况,您可以在map[""]