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

当我尝试从另一个扩展方法(重载该方法)调用扩展方法时,它不能在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) 

提前致谢!

还有其他的答案,但是这里有更多关于正在发生什么的笔记,下面是一个类似的解决方案,它保持方法命名,避免递归,并为这两个方法签名保留varargs

  • 当将一个可变参数传递给另一个可变参数时,需要使用spread运算符,因为可变参数是以数组的形式接收的,您想要将它们转换回参数列表,并且传播运算符就是这样做的。

  • fold() lambda中的调用意外地调用它自己。 既然你用2个参数调用string.replace() ,哪个版本胜出? 版本string.replace(String, String, vararg Pair<String,String>)或者string.replace(String, String, Boolean[defaulted to false]) ? 只有用2个参数调用时,它们看起来都是一样的。 而本地的一个赢,所以你有递归。 要强制对stdlib替换函数进行调用,第三个参数默认为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 } 

你的问题是,第一个String.replace递归调用自己,主String.replace永远不会到达。 而且,第二个变量被作为一个数组传递给第一个,因此调用第二个函数将永远不会匹配第一个。

 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) }) 

就像我虽然这是一个bug,我搜索到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)