【问题标题】:Kotlin extension method as alias for long method name?Kotlin 扩展方法作为长方法名称的别名?
【发布时间】:2017-10-08 12:51:37
【问题描述】:

我正在使用 Kotlin 本地库对象在 Kotlin 中工作,该对象包含 .nameIsMuchTooLongAndIsStillNotClear 的方法。以类似于typealias 的方式,我想为该方法创建一个别名,因此我可以将其称为.shortAndClear。为了使事情稍微复杂化,这些函数有几个参数,其中许多具有我不希望在包装器中预处理的默认值。经过进一步研究,extension function 似乎仍然是要走的路。

要使用易于测试的示例函数,假设我想为String.startsWith 创建一个别名类型的扩展名,称为String.beg。我可以轻松获得以下解决方案:

inline fun String.beg(prefix: CharSequence, ignoreCase: Boolean = false) = startsWith(prefix, ignoreCase)   // works ok

但是,这似乎要求我列出所有参数及其默认值,并且对每个重载都这样做。 (有问题的真正方法签名要长得多,有更多的默认值。)本着“不要重复自己”的精神,有没有办法可以使用function referenceString::startsWith,这样我就没有枚举所有论点?我已经尝试了几种形式,但它们都不起作用:

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

【问题讨论】:

    标签: kotlin extension-methods kotlin-extension


    【解决方案1】:

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

    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
    

    【讨论】:

      【解决方案2】:

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

      import kotlin.text.startsWith as beg
      
      fun main() {
          "foo".beg("fo")
          "bar".beg('B', true)
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-29
        • 1970-01-01
        • 2022-01-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多