问题在评论中。我想引用外部函数append
,而不是StringBuilder
中定义的外部函数,我该怎么做?
fun append(c: Char) {
println("TEST")
}
fun sbTest() = with(StringBuilder()) {
for(c in 'A'..'Z') {
append(c) // how do I refer to the append function declared above?
}
toString()
}
我知道我可以引入一个函数引用变量,如下所示:
val f = ::append
并调用f
而不是append
,但是还有另一种方法吗?
答案 0 :(得分:5)
问题在于,with
内的任何调用都遮盖了外部函数,因为引入了this
。如果您有一个类和一个具有相同签名的函数的顶级函数,则会出现相同的问题。
显而易见的选择就是重新命名。而且,您所拥有的功能与其实际功能相比并没有真正的描述性。但是,如果由于某种原因而无法重命名,则还有其他选择。
对于com.some.package.method
之类的实例,Kotlin中的包可以引用顶级方法。也可以将其原样导入,这是最常用的方法。很少有被称为com.some.package.method()
的方法。
Kotlin与Python一样,允许as
导入。也就是说,您可以执行以下操作:
package com.example;
// This is the important line; it declares the import with a custom name.
import com.example.append as appendChar; // Just an example name; this could be anything ***except append***. If it's append, it defeats the purpose
fun append(c: Char) {
println("TEST")
}
fun sbTest() = with(StringBuilder()) {
for(c in 'A'..'Z') {
appendChar(c)
}
toString()
}
或者,正如我提到的,您可以添加软件包:
for(c in 'A'..'Z') {
com.example.append(c)
}
val f = ::append
当然也是一个选项,无论哪种方式,重命名该函数都比使用as
或常量创建导入要容易得多,前提是您有权使用该函数(并且不属于依赖项)。
如果您的文件不在软件包中,我不建议您这样做,则可以将导入声明为:
import append as appendChar
答案 1 :(得分:2)
您也可以使用扩展功能代替with()
,例如.let{...}
。
这会将StringBuilder
作为扩展函数的参数发送为it
(您可以将其重命名为您想要的任何东西)
fun sbTest() = StringBuilder().let{ it ->
for(c in 'A'..'Z') {
// using string builder
it.append(c)
// using your function
append(c)
}
it.toString()
}
.let{...}
函数返回您的最后一条语句,也就是toString()
中的字符串,因此您的原始函数仍会正确返回它。其他函数可以返回this
,例如.also{...}
我倾向于使用扩展功能而不是with()
,因为它们更灵活。
请参阅此文章以掌握扩展功能:https://medium.com/@elye.project/mastering-kotlin-standard-functions-run-with-let-also-and-apply-9cd334b0ef84
编辑:混合了also{}
和let{}
。我换了