Kotlin扩展方法作为长方法名的别名?

sir*_*sel 5 extension-methods kotlin kotlin-extension

我在Kotlin工作,使用包含方法的Kotlin本地库对象.nameIsMuchTooLongAndIsStillNotClear.以类似的方式typealias,我想为方法创建一个别名,所以我可以将它称为某种东西.shortAndClear.稍微复杂一点,这些函数有几个参数,其中许多都有默认值,我不想在包装器中预处理.经过进一步的研究,它似乎仍然是一种扩展功能.

要使用示例函数,很容易测试,让我们说我要为创建别名类型的扩展String.startsWith被称为String.beg.我可以很容易地得到以下解决方案:

inline fun String.beg(prefix: CharSequence, ignoreCase: Boolean = false) = startsWith(prefix, ignoreCase)   // works ok
Run Code Online (Sandbox Code Playgroud)

但是,这似乎要求我列出所有参数及其默认值,并为每次重载执行此操作.(真正的方法签名相当长,有更多的默认值.)本着"不要重复自己"的精神,有没有办法可以使用函数引用,String::startsWith这样我就不必枚举所有参数?我尝试了几种形式,但它们都不起作用:

// none of these work:
fun String.beg = String::startsWith
fun String.beg = this::startsWith
val String.beg: (CharSequence, Boolean) -> Boolean = String::startsWith
Run Code Online (Sandbox Code Playgroud)

Dea*_*eef 6

您还可以使用导入别名,例如:

import kotlin.text.startsWith as beg

fun main() {
    "foo".beg("fo")
    "bar".beg('B', true)
}
Run Code Online (Sandbox Code Playgroud)


Gio*_*oli 5

目前,没有办法完全实现你想要做的事情.如果你想保留你的默认参数,你必须这样做(如你所说):

fun String.beg(prefix: CharSequence, ignoreCase: Boolean = false) = startsWith(prefix, ignoreCase)
// Or if you know that ignoreCase will be always false, you can pass the value directly to "startsWith()
fun String.beg(prefix: CharSequence) = startsWith(prefix, false)
Run Code Online (Sandbox Code Playgroud)

相反,如果您没有默认参数,或者在调用函数时不必关心是否必须传递默认值,则可以使用函数引用.

val String.beg: (CharSequence, Boolean) -> Boolean get() = this::startsWith
// If the parameters can be inferred, you can avoid the type specification.
// In this case it won't compile because there are several combinations for "startsWith()".
val String.beg get() = this::startsWith
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您不能指定参数的默认值,因为它beg是一个lambda.

从Kotlin 1.2(目前处于测试版)开始,您可以避免this在函数引用上指定.上面写的相同例子但在Kotlin 1.2中:

val String.beg: (CharSequence, Boolean) -> Boolean get() = ::startsWith
// If the parameters can be inferred, you can avoid the type specification.
// In this case it won't compile because there are several combinations for "startsWith()".
val String.beg get() = ::startsWith
Run Code Online (Sandbox Code Playgroud)