Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Intellij idea 从Kotlin中的另一个扩展方法调用扩展方法时发生编译错误_Intellij Idea_Kotlin_Intellij 14 - Fatal编程技术网

Intellij idea 从Kotlin中的另一个扩展方法调用扩展方法时发生编译错误

Intellij idea 从Kotlin中的另一个扩展方法调用扩展方法时发生编译错误,intellij-idea,kotlin,intellij-14,Intellij Idea,Kotlin,Intellij 14,当我尝试从另一个扩展方法调用扩展方法(重载该方法)时,它不会在Intellij14.1.5和Kotlin0.14.449中编译 由于我对该语言不熟悉,在参考资料中也不禁止这样做,我想知道: 是否可以从另一个扩展方法调用扩展方法 我使用的语法正确吗(因此这是一个bug) 如果不是,正确的语法是什么 这是未编译的代码: fun String.replace (prefix: String, suffix: String, vararg parameters: Pair<String, St

当我尝试从另一个扩展方法调用扩展方法(重载该方法)时,它不会在Intellij14.1.5和Kotlin0.14.449中编译

由于我对该语言不熟悉,在参考资料中也不禁止这样做,我想知道:

  • 是否可以从另一个扩展方法调用扩展方法
  • 我使用的语法正确吗(因此这是一个bug)
  • 如果不是,正确的语法是什么
这是未编译的代码:

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)
fun String.replace(前缀:String,后缀:String,vararg参数:Pair)=
parameters.fold(这,{result,pair->result.replace(前缀+pair.first+后缀,pair.second)})
fun String.replace(vararg参数:对)=
this.replace(“,”,参数)

提前谢谢

您的问题是,第一个String.replace递归地调用自己,而主String.replace永远不会到达。另外,第二个函数中的vararg以数组>的形式传递给第一个函数,因此调用第二个函数永远不会与第一个函数匹配

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) })
fun String.replace(vararg参数:对)=
替换(“,”,参数)
有趣的字符串。替换(前缀:字符串,后缀:字符串,参数:数组)=
parameters.fold(这,{result,pair->result.replace(前缀+pair.first+后缀,pair.second)})

我认为这是一个bug,我搜索了Kotlin问题追踪器,发现了以下内容:

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)
fun String.filter(前缀:String,后缀:String,vararg参数:Pair)=
parameters.fold(这,{result,pair->result.replace(前缀+pair.first+后缀,pair.second)})
fun String.filter(vararg参数:对)=
this.filter(“,”,*参数)

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

  • 在将一个vararg传递给另一个vararg时,需要使用,因为vararg是作为数组接收的,您希望将它们转换回参数列表,而spread操作符正是这样做的

  • fold()
    lambda中的调用意外地调用了自身。既然您使用2个参数调用了
    string.replace()
    ,那么哪个版本获胜?版本
    string.replace(string,string,vararg对)
    string.replace(string,string,Boolean[默认为false])
    ?当仅使用2个参数调用时,它们看起来都一样。本地的一个赢了,所以你有递归。要强制调用stdlib replace函数,第三个参数默认为
    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
}
fun String.replace(前缀:String,后缀:String,vararg参数:Pair){
参数。折叠(此){结果,对->
//添加最后一个参数来区分我想要调用的版本,即带有可选参数的版本
//布尔参数last(ignoreCase:boolean=false)。否则这会在意外情况下再次出现。
结果.替换(前缀+pair.first+后缀,pair.second,false)
}
}
有趣的字符串.replace(vararg参数:Pair){
this.replace(“,”“,*参数)//添加*扩展运算符
}

在第二个函数中,我尝试调用第一个函数。参数与第二个函数不匹配(因此它不应该是递归调用)。无论如何,这将是一个运行时错误,但我得到一个编译错误。我缺少什么吗?this.replace(“,”,参数)不匹配,因为vararg不会转换为另一个vararg,而是转换为一个数组。您的第一个函数给出了一个错误结果。replace(2)是一个递归调用,这是因为vararg将在0和pair上匹配。first和pair.second是字符串,而String.replace(1)函数需要vararg对。您不应该避免第二个函数中的
vararg
,您可以将最后一个布尔参数添加到函数内的
replace
调用中,以便它调用正确的运行时函数,而不是递归。Kotlin中的大量代码从一个扩展函数调用另一个扩展函数。问题在于您的代码,因为它是错误的。到目前为止,你有两个错误的答案。我将添加一个新的答案。您接受的答案无效,您可以检查并编辑它以确保正确,或者更改为正确的答案吗?此答案对于Kotlin 1.0 betas+不正确,因为它会导致第一个方法内的递归,因为该方法本身会覆盖尝试调用的版本(varargs可以省略,
string.replace(string,string,boolean[optional])
)的第三个布尔参数也可以省略。因此,本地函数是赢的,也是错的。我必须用我的单元测试来检查它……但到目前为止,我的项目正在使用Kotlin 1.0 beta。无论如何,方法符号是
string.replace(vararg对)
…因此,在同一个方法中首先使用两个字符串调用它永远不会解析为同一个方法。它是调用自身的方法的另一种形式,在您的回答中,顶部的一个使用
string,string,vararg:Pair
fold
lambda中意外调用自身。或者可能是为了递归?I di不要查看逻辑以查看递归是否有意义,但看起来您的意思是调用
string、string、boolean(默认值)
version而不是stdlib。如果不是,请告诉我,因为我的答案是错误的。此外,发布一个单元测试是有用的,因为它显示了预期的结果。我使用Kotlin 1.0 betaSyntax错误进行测试,这不会编译。第二个函数调用
replace
而不是
filter
。它通过重命名来避免递归筛选而不是保留名称