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

Kotlin的函数样式主函数参数解析,kotlin,parameter-passing,Kotlin,Parameter Passing,如果我用这种方式写问答题不合适,请告诉我。另外,我也期待着一些更好的答案。我提供的两种解决方案并不完美 例如,现在互联网上有一些Kotlin参数解析器,或者。然而,我不想在我(可能)的小项目中添加这么大的文件夹。我想要的是一个简单而干净的解决方案,例如一个函数,具有“流畅”的流式实现。相反,这些项目都包含几个文件 我的想法是,只需要将命令行参数解析为Map,使用Map.containsKey()获取无参数参数,使用Map[key]获取必需参数参数 例如,命令行参数列表 -a -b c -d e

如果我用这种方式写问答题不合适,请告诉我。另外,我也期待着一些更好的答案。我提供的两种解决方案并不完美

例如,现在互联网上有一些Kotlin参数解析器,或者。然而,我不想在我(可能)的小项目中添加这么大的文件夹。我想要的是一个简单而干净的解决方案,例如一个函数,具有“流畅”的流式实现。相反,这些项目都包含几个文件

我的想法是,只需要将命令行参数解析为
Map
,使用
Map.containsKey()
获取
无参数
参数,使用
Map[key]
获取
必需参数
参数

例如,命令行参数列表

-a -b c -d e f g -h --ignore --join k --link m n o -p "q r s"
将被解析为:

{-a=[], -b=[c], -d=[e, f, g], -h=[], --ignore=[], --join=[k], --link=[m, n, o], -p=[q r s]}
或者我们说

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
)

这是我的实现

fun getopt(args: Array<String>): Map<String, List<String>> = args.fold(mutableListOf()) {
    acc: MutableList<MutableList<String>>, s: String ->
    acc.apply {
        if (s.startsWith('-')) add(mutableListOf(s))
        else last().add(s)
    }
}.associate { it[0] to it.drop(1) }
fun getopt(args:Array):Map=args.fold(mutableListOf()){
acc:MutableList,s:String->
根据申请{
如果(s.startsWith('-'))添加(可变列表)
else last()。添加
}
}.associate{it[0]到它。drop(1)}

使用
fold
将参数与其对应的参数分组(即,将
[-p0 arg0 arg1-p1 arg2]
转换为
[-p0,arg0,arg1],-p1,arg2]
),然后将
关联到
映射中。此函数是流式处理,但需要2次数据传递。此外,如果有一些前导参数没有前面的参数,则会导致异常。

下面是另一个实现:

fun getopt(args: Array<String>): Map<String, List<String>>
{
    var last = ""
    return args.fold(mutableMapOf()) {
        acc: MutableMap<String, MutableList<String>>, s: String ->
        acc.apply {
            if (s.startsWith('-'))
            {
                this[s] = mutableListOf()
                last = s
            }
            else this[last]?.add(s)
        }
    }
}
fun getopt(args:Array):映射
{
var last=“”
返回args.fold(mutableMapOf()){
acc:MutableMap,s:String->
根据申请{
如果(s.startsWith('-'))
{
此[s]=mutableListOf()
last=s
}
否则此[最后]?。添加
}
}
}

直接构造映射结构,但应保留最后一个参数的引用以添加下一个参数。这个函数不是流式的,但是只需要一次数据传递。它只是简单地丢弃了没有前一个参数的前导参数。

好吧,我的解决方案包括不变性和使用
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)
}

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

使用的minium Kotlin版本是什么
getOrDefault
{-a=[], -b=[c], -d=[e, f, g], -h=[], --ignore=[], --join=[k], --link=[m, n, o], -p=[q r s]}