编译从Kotlin中的另一个扩展方法调用扩展方法的错误

时间:2015-10-12 11:08:45

标签: intellij-idea kotlin intellij-14

当我尝试从另一个扩展方法调用扩展方法(重载该方法)时,它无法在IntelliJ 14.1.5和Kotlin 0.14.449中编译

由于我是该语言的新手,并且在参考文献中并没有禁止这样做,我想知道:

  • 可以从另一种扩展方法调用扩展方法吗?
  • 我使用的语法是否正确(因此这是一个错误)?
  • 如果没有,那么正确的语法是什么?

这是无法编译的代码:

fun String.replace (prefix: String, suffix: String, vararg parameters: Pair<String, String>) =
    parameters.fold(this, { result, pair -> result.replace (prefix + pair.first + suffix, pair.second) })

fun String.replace (vararg parameters: Pair<String, String>) =
    this.replace ("", "", parameters)

提前致谢!

3 个答案:

答案 0 :(得分:2)

还有其他答案,但是这里有更多关于发生了什么的注释,并且遵循类似的解决方案,保持方法命名,避免递归,并为两个方法签名保留varargs

  • 当将一个varargs传递给另一个varargs时,你需要使用spread operator,因为varargs是作为一个数组接收的,你想将它们转换回参数列表,而扩展运算符就是这样。< / p>

  • fold() lambda内部的调用意外地调用了自己。由于您使用2个参数调用string.replace(),哪个版本获胜?版本string.replace(String, String, vararg Pair<String,String>)string.replace(String, String, Boolean[defaulted to false])?当仅使用2个参数调用时,它们看起来都相同。而本地人赢了,因此你有递归。要强制调用stdlib替换函数,第3个参数默认为false,因此专门传递该值以便找到正确的方法签名。

工作代码:

fun String.replace(prefix: String, suffix: String, vararg parameters: Pair<String, String>) {
    parameters.fold(this) { result, pair ->
        // add a last parameter to differentiate what version I want called, the one with optional
        // boolean parameter last (ignoreCase: Boolean = false).  Otherwise this recurses on accident.
        result.replace(prefix + pair.first + suffix, pair.second, false)
    }
}

fun String.replace(vararg parameters: Pair<String, String>) {
    this.replace ("", "", *parameters) // add * spread operator
}

答案 1 :(得分:0)

您的问题是第一个String.replace递归调用自身,并且永远不会到达主String.replace。此外,第二个中的vararg作为数组传递给第一个&gt;所以调用第二个函数永远不会匹配第一个函数。

fun String.replace(vararg parameters: Pair<String, String>) =
        this.replace("", "", parameters)

fun String.replace(prefix: String, suffix: String, parameters: Array<out Pair<String, String>>) =
        parameters.fold(this, { result, pair -> result.replace(prefix + pair.first + suffix, pair.second) })

答案 2 :(得分:0)

虽然这是一个错误,但我搜索了Kotlin问题跟踪器,发现了这个:https://youtrack.jetbrains.com/issue/KT-2079

vararg参数传递给另一个函数的正确语法是使用星号'*':

fun String.filter (prefix: String, suffix: String, vararg parameters: Pair<String, String>) =
    parameters.fold(this, { result, pair -> result.replace (prefix + pair.first + suffix, pair.second) })

fun String.filter (vararg parameters: Pair<String, String>) =
    this.filter("", "", *parameters)