Как использовать функцию расширения Kotlin на классе? - PullRequest
3 голосов
/ 10 октября 2019

У меня довольно короткий вопрос о функции расширения, которая поможет очистить часть моего кода. В основном у меня есть некоторые преобразования в hashCode имени класса, и я хочу, чтобы функция расширения выполняла преобразования.

Пример:

Получение имени hashCode: StateA::class.java.name.hashCode() где StateA - это простоеclass.

Я хочу использовать функцию расширения, например:

    fun Class<*>.transformName(): String {
       var hashString = this.javaClass.name.hashCode()

       //Do my stuff on that hashString

       return hashString
    }

Но, похоже, это не работает. Когда я применяю функцию расширения с помощью StateA.transformName(), функция выдает ошибку с Unresolved Reference.

Я пробовал разные вещи, такие как применение функции к StateA::class или значение hashString, равное this::class.java.name.hashCode(), но ничегоработает. Любые советы?

1 Ответ

8 голосов
/ 10 октября 2019

Вы не можете действительно достичь синтаксиса StateA.transformName(), так как StateA само по себе относится к объекту-компаньону внутри этого класса. Таким образом, чтобы получить этот синтаксис, вам нужно иметь сопутствующий объект внутри каждого класса, для которого вы хотите использовать это расширение.

Что вы можете сделать в самом общем виде, так это получить KClass, который описываетваш класс первым. Это дает вам объект (экземпляр KClass), для которого вы затем можете вызвать расширение:

fun KClass<*>.transformName() {
    val clazz: Class<*> = this.java
    clazz.name.hashCode()
}

StateA::class.transformName()

Другой подход, который является менее многословным на сайте вызова, может быть общей функцией, подобной этой, гдеключевое слово reified позволяет получить доступ к конкретному классу, который использовался в качестве параметра универсального типа внутри функции:

inline fun <reified T> transformName() {
    val clazz: Class<*> = T::class.java
    clazz.name.hashCode()
}

transformName<StateA>()
...