Могут ли функции расширения быть вызваны «статическим» способом?

Возможно ли создать функцию расширения и вызвать ее так, как если бы она была статичной ?

Например…

fun System.sayByeAndExit() { println("Goodbye!") System.exit() } fun main(args: Array<String>) { System.sayByeAndExit() // I'd like to be able to call this } 

Я знаю, что образец кода не работает …

Зачем мне это нужно?

Некоторым из вас может быть интересно, почему это поведение желательно. Я могу понять, почему вы думаете, что это не так, поэтому вот несколько причин:

  1. Он обладает всеми преимуществами, предоставляемыми стандартными функциями расширения.
  2. Экземпляр класса не нужно создавать только для доступа к дополнительным функциям.
  3. Доступ к функциям возможен из общесистемного контекста (при условии, что класс виден).

Обобщить…

Есть ли у Kotlin способ «привязать» статическую функцию к классу? Мне бы очень хотелось узнать.

Вы действительно просите «функции расширения для ссылки на класс» или «добавление статических методов к существующим классам», на что был обращен еще один вопрос: как добавить статические методы в классы Java в Котлине, которые покрываются запросом функции KT- 11968

Функции расширения не могут быть добавлены ни к чему, у которого нет экземпляра. Ссылка на класс не является экземпляром, поэтому вы не можете расширять что-то вроде java.lang.System . Однако вы можете расширить объект-компаньон существующего класса. Например:

 class LibraryThing { companion object { /* ... */ } } 

Позволяет расширять LibraryThing.Companion и поэтому вызов некоторого нового myExtension() будет выглядеть так, как будто вы расширяете ссылку на класс, когда действительно расширяете экземпляр singleton объекта-компаньона:

 fun LibraryThing.Companion.myExtension() = "foo" LibraryThing.Companion.myExtension() // results in "foo" LibraryThing.myExtension() // results in "foo" 

Поэтому вы можете обнаружить, что некоторые библиотеки Kotlin добавляют пустые объекты-компаньоны только для этого случая. Других нет, и для тех, кому «не повезло». Поскольку Java не имеет сопутствующих объектов, вы не можете сделать то же самое и для Java.

Другой часто запрашиваемой функцией является использование существующего Java-статического метода, который принимает экземпляр класса в качестве первого параметра и заставляет его вести себя как функция расширения. Это отслеживается проблемами KT-5261 , KT-2844 , KT-732 , KT-3487 и, возможно, другими функциями.

Вы можете определить функцию расширения для object и использовать его из общесистемного контекста. Объект будет создан только один раз.

 object MyClz fun MyClz.exit() = System.exit(0) fun main(args: Array<String>) { MyClz.exit() } 

Или

 class MyClz { companion object } fun MyClz.Companion.exit() = System.exit(0) fun main(args: Array<String>) { MyClz.exit() } 
  • Kotlin: получить ссылку на функцию экземпляра класса
  • Kotlin - Как я могу получить доступ к моей новой функции расширения класса из другого файла
  • когда использовать встроенную функцию в Котлин?
  • Превознесение Клейсли в Котлине
  • Как сделать возвращаемый тип функции переопределения одного выражения для Unit?
  • Могу ли я иметь другой тип возврата в котлин?
  • перегрузка + и + = операторов для «классов номеров»
  • Как получить доступ к членам класса с таким же именем в функции расширения в Kotlin android
  • Объяснить эту структуру функций Котлина
  • Kotlin: Можете ли вы использовать именованные аргументы для varargs?
  • Kotlin - Расходы на более высокие порядки?
  • Interesting Posts

    Поддерживает ли Kotlin деревья выражений?

    Модуль Plain Kotlin в Android Studio 3.0, `api` не поддерживается?

    Вычислить свойство только один раз

    Преобразование вызова функции в Lambda (SAM)

    Различные вопросы @NonNull, @NotNull и @ParametersAreNonnullByDefault

    Почему Котлин использует слово «val» для постоянных?

    прослушивание сокетов на клиентском и голосовом сервисе для Android-мессенджера

    Ошибка переноса подпункта: com.android.dx.cf.code.SimException: local 0007: недействительный

    Таймер сбой с KotlinNullPointerException внутри фрагмента

    Android 4.x VerifyError, вызванный методом Котлина

    Можем ли мы достичь безопасности типа компиляции для объединения типов, которые мы не можем контролировать?

    Выполнение Android не выполнено для задачи app.compileDebugKotlin, когда используется firebase

    Как установить JsName для поля поддержки свойства в Kotlin?

    Ошибка в печатном простом номере с использованием функций высокого порядка в котлине

    Java / Kotlin: Почему разборки Джексона датируются иначе, чем SimpleDateFormat?

    Давайте будем гением компьютера.