Kotlin 扩展方法作为长方法名称的别名?
Kotlin extension method as alias for long method name?
我在 Kotlin 中工作,使用包含 .nameIsMuchTooLongAndIsStillNotClear
方法的 Kotlin 原生库对象。以类似于 typealias
的方式,我想为该方法创建一个别名,因此我可以将其称为 .shortAndClear
。使事情稍微复杂化的是,这些函数有几个参数,其中许多参数有我不希望在包装器中预处理的默认值。经过进一步研究,似乎 extension function 是可行的方法。
要使用易于测试的 示例函数 ,假设我想为 String.startsWith
创建一个名为 String.beg
的别名类型扩展.我可以轻松地使用以下解决方案:
inline fun String.beg(prefix: CharSequence, ignoreCase: Boolean = false) = startsWith(prefix, ignoreCase) // works ok
但是,这似乎要求我列出所有参数及其默认值,并在每次重载时都这样做。 (有问题的实际方法签名相当长,默认值更多。)本着 "don't repeat yourself" 的精神,有没有办法我可以使用 function reference 到 String::startsWith
这样我就不会不必枚举所有参数?我尝试了几种形式,但其中 none 有效:
// none of these work:
fun String.beg = String::startsWith
fun String.beg = this::startsWith
val String.beg: (CharSequence, Boolean) -> Boolean = String::startsWith
目前没有办法完全实现您的目标。如果你想保留你的默认参数,你必须这样做(如你所说):
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)
相反,如果您没有默认参数,或者您不关心在调用函数时是否必须传递默认值,则可以使用函数引用。
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
在这种情况下,您无法指定参数的默认值,因为 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
您也可以使用导入别名,例如:
import kotlin.text.startsWith as beg
fun main() {
"foo".beg("fo")
"bar".beg('B', true)
}
我在 Kotlin 中工作,使用包含 .nameIsMuchTooLongAndIsStillNotClear
方法的 Kotlin 原生库对象。以类似于 typealias
的方式,我想为该方法创建一个别名,因此我可以将其称为 .shortAndClear
。使事情稍微复杂化的是,这些函数有几个参数,其中许多参数有我不希望在包装器中预处理的默认值。经过进一步研究,似乎 extension function 是可行的方法。
要使用易于测试的 示例函数 ,假设我想为 String.startsWith
创建一个名为 String.beg
的别名类型扩展.我可以轻松地使用以下解决方案:
inline fun String.beg(prefix: CharSequence, ignoreCase: Boolean = false) = startsWith(prefix, ignoreCase) // works ok
但是,这似乎要求我列出所有参数及其默认值,并在每次重载时都这样做。 (有问题的实际方法签名相当长,默认值更多。)本着 "don't repeat yourself" 的精神,有没有办法我可以使用 function reference 到 String::startsWith
这样我就不会不必枚举所有参数?我尝试了几种形式,但其中 none 有效:
// none of these work:
fun String.beg = String::startsWith
fun String.beg = this::startsWith
val String.beg: (CharSequence, Boolean) -> Boolean = String::startsWith
目前没有办法完全实现您的目标。如果你想保留你的默认参数,你必须这样做(如你所说):
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)
相反,如果您没有默认参数,或者您不关心在调用函数时是否必须传递默认值,则可以使用函数引用。
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
在这种情况下,您无法指定参数的默认值,因为 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
您也可以使用导入别名,例如:
import kotlin.text.startsWith as beg
fun main() {
"foo".beg("fo")
"bar".beg('B', true)
}