Kotlin extension method as alias for long method name?

孤者浪人 提交于 2020-01-24 04:38:07

问题


I am working in Kotlin using a Kotlin-native library object containing a method whose .nameIsMuchTooLongAndIsStillNotClear. In a manner similar to typealias, I want to create an alias to the method, so I can refer to it as something .shortAndClear. To complicate matters slightly, these functions have several parameters, many of which have defaults that I'd prefer not to pre-process in a wrapper. After further research, it still seems like an extension function is the way to go.

To use an example function that's easy to test, let's say I want to create an alias-type extension for String.startsWith that is called String.beg. I can easily get the following solution to work:

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

However, this seems to require that I list all argument and their defaults, and do so for every overload. (The real method signatures in question are considerably longer with many more defaults.) In the spirit of "don't repeat yourself", is there a way I can use a function reference to String::startsWith so that I don't have to enumerate all arguments? I've tried several forms, but none of them work:

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

回答1:


Currently there's no way to fully achieve what you are trying to do. If you want to keep your default parameters, you have to do (as you said):

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)

Instead, if you haven't default parameters or you don't care if you have to pass the default value when you will invoke the function, you can use a function reference.

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

In this case, you can't specify the default value of a parameter because beg is a lambda.

Since Kotlin 1.2 (currently in beta), you can avoid to specify this on a function reference. Same examples written above but in 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


来源:https://stackoverflow.com/questions/46631293/kotlin-extension-method-as-alias-for-long-method-name

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!