代码之家  ›  专栏  ›  技术社区  ›  Les

以Vararg为第一参数的Kotlin方法

  •  6
  • Les  · 技术社区  · 7 年前

    笔记 Call Java Varargs Method from Kotlin -这个参数列表的末尾有varargs参数,但我的问题是在参数列表的开头处理varargs。 Kotlin: Convert List to Java Varargs

    我给Kotlin打电话 String.split 具有单字符分隔符的方法。 vararg 方法,其中 瓦拉格 参数是多个参数中的第一个。该方法的定义如下:

    public fun CharSequence.split(vararg delimiters: Char, 
                                  ignoreCase: Boolean = false,
                                  limit: Int = 0): List<String>
    

    当我按如下方式调用该方法时,它编译得很好:

    fun String.splitRuleSymbol() : String = this.split(':') //ok
    

    但是当我尝试添加 ignoreCase limit 参数,我遇到了一个问题:

    fun String.splitRuleSymbol() : String = this.split(':', true, 2) //compiler error
    

    我得到的错误是。。。

    公共娱乐节目。拆分(vararg分隔符:String,ignoreCase:Boolean=…,limit:Int=…):kotlin中定义的列表。文本

    公共娱乐节目。拆分(vararg分隔符:Char,ignoreCase:Boolean=…,limit:Int=…):kotlin中定义的列表。文本

    对我来说 瓦拉格 参数后面跟着其他参数有点奇怪,但这离题了。如果我这样称呼它,它工作得很好:

     // both of the following compile
     fun String.splitRuleSymbol() : String = 
               this.split(delimiters = ':', ignoreCase = true, limit = 2)
     fun String.splitRuleSymbol2() : String = 
               this.split(';', ignoreCase = true, limit = 2)
    

    有没有办法通过 vararg Char 忽略案例 限度 编译器能否不告诉其余参数不是 Char ?

    我试过了 the spread operator

        //compiler errors on all these
        this.split(*':', true, 2) //using the "spread" operator
        this.split(*charArrayOf(':'), true, 2)
        this.split(*mutableListOf(':'), true, 2)
        this.split(*Array<Char>(1) { ':' }, true, 2)
    

    是的,我知道有些看起来很可笑。但是,没有办法避免冗长的选择吗?

    当我阐述我的问题时,我发现了另一个编译过的表达式。

        this.split(':', limit = 2)
    

    这没有那么冗长,因为我不需要更改默认值 参数,它更接近我想要的。

    3 回复  |  直到 7 年前
        1
  •  10
  •   zsmb13    7 年前

    vararg 参数只能通过使用命名参数传递,否则会遇到歧义问题(举个小例子,假设所有参数都是类型) Any

    我现在能找到的最好的消息来源是 book .

    编辑:@Les找到了一个很好的来源,请参阅 their answer

        2
  •  6
  •   Les    7 年前

    多亏了zsmb13,我才能够在 Kotlin Specification (在“功能和lambda”下)

    不是列表中的最后一个,以下参数的值可以 使用命名参数语法传递,或者,如果参数具有 函数类型,通过在括号外传递lambda。

    我冒昧地补充说,“可以传递”应该改为“必须传递”,因为编译器不允许这样做。

    笔记 lambda部分很有趣,因为规范通常只允许在lambda为 最后的 vararg 参数,但实验表明,它不能,也就是说,它必须是最后一个参数,才能移出括号。

    fun main(args: Array<String>) {
        test("hello", limit = 1, ic = false, delims = ';') { } //ok
        //test2("world", limit = 1, ic = false, delims = ';') { } //error
        test2("world", f = {}, limit = 1, ic = false, delims = ';') //ok
        test("hello world", ';', limit = 1, ic = false) {}  //ok
    }
    
    fun test(vararg delims: Char, ic: Boolean, limit: Int, f: () -> Unit) {} 
    fun test2(vararg delims: Char, f: () -> Unit, ic: Boolean, limit: Int) {} 
    
        3
  •  2
  •   Rajesh Dalsaniya    7 年前

    变量数量(vararg)可以使用扩展运算符以命名形式传递:

    fun foo(vararg strings: String) { /* ... */ }
    
    foo(strings = *arrayOf("a", "b", "c"))
    foo(strings = "a") // Not required for a single value