Intereting Posts
Android-библиотека не может компилировать kotlin Джексон @JsonAppend со значением по умолчанию Второй конструктор класса Kotlin с другим параметром android.view.InflateException: двоичная строка XML-файла # 0: ошибка раздувания класса android.support.design.widget.TextInputEditText Как сохранить ссылку функции как значение в типе карты и вызвать ее с параметром позже в Котлин? Почему вызовы должны быть вызваны с помощью вызова класса класса? Смарт-бросок в BootsrapButton невозможен, потому что endtrip является изменчивым свойством, которое к этому времени изменилось JUnit, @ControllerAdvice и отсутствие проверенных исключений в Kotlin String :: toByteArray () не компилируется в Kotlin Android gradle build неожиданно отключается в ': app: mergeDebugResources' без сообщений об ошибках Не удается создать проект с Android Studio 3.0 + DataBinding + Kotlin Gradle sinc не удалось с расширением kotlin. для строки ввода: "" в файле build.gradle file module (app) Как реализовать finalize () в котлин? Kotlin with-statement как выражение Kotlin JSR-223 ScriptEngineFactory в толстой банке – Не удается найти компилятор kotlin компилятора

Функции расширения Котлина и функции-члены?

Я знаю, что функции расширения используются в Kotlin для расширения функциональности класса (например, одного из библиотеки или API).

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

class Foo { ... } fun Foo.bar() { // Some stuff } 

В отличие от функций-членов:

 class Foo { ... fun bar() { // Some stuff } } 

?

Есть ли рекомендуемая практика?

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

  1. Чтобы «расширить» поведение класса, вы не являетесь автором / не можете изменить (и где наследование не имеет смысла или не представляется возможным).

  2. Предоставить возможности для конкретной функциональности. Например, функция расширения может быть объявлена ​​как автономная функция, и в этом случае ее можно использовать повсюду. Или вы можете объявить его как (частную) функцию-член другого класса, и в этом случае она может использоваться только внутри этого класса.

Похоже, что №1 не вызывает беспокойства в вашем случае, так что это действительно больше, чем №2.

Когда использовать функции-члены

Вы должны использовать функции-члены, если применимы все следующие условия:

  • Код написан первоначально в Котлине
  • Вы можете изменить код
  • Метод имеет смысл использовать любой другой код

Когда использовать функции расширения

Вы должны использовать функции расширения, если выполнено одно из следующих действий:

  • Код был первоначально написан на Java, и вы хотите добавить методы, написанные в Kotlin
  • Вы не можете изменить исходный код
  • Вам нужна специальная функция, которая имеет смысл только для определенной части кода

Зачем?

Как правило, функции-члены легче найти, чем функции расширения, поскольку они гарантированы в классе, в котором они являются членами (или супер-класса / интерфейса).

Им также не нужно импортировать весь код, который их использует.

Функции расширения аналогичны функциям, которые вы создаете как служебные функции.

Основным примером может быть следующее:

 // Strings.kt fun String.isEmail() : Boolean { // check for email pattern and return true/false } 

Этот код можно записать как служебную функцию в Java следующим образом:

 class StringUtils { public static boolean isEmail(String email) { // check for email pattern and return true/false } } 

Так что, по сути, это то, что вызов той же функции с вызываемым объектом будет передан в качестве первого параметра аргумента. Подобно той же функции, которую я привел на примере Java .

Если вы хотите вызвать функцию расширения, созданную в kotlin из java , вам необходимо передать вызывающего в качестве первого аргумента. Подобно,

 StringsKt.isEmail("example@example.com") 

Согласно документации,

Расширения фактически не изменяют классы, которые они расширяют. Определяя расширение, вы не вставляете новые члены в класс, а просто делаете новые функции вызываемыми с помощью точечной нотации на переменные этого типа.

Это просто статические функции с вызывающим в качестве первого аргумента и другими параметрами, за которыми следует его. Это просто расширяет возможности для нас писать так.

Когда создавать функции расширения?

  • Когда у вас нет доступа к этому классу. Когда этот класс принадлежит какой-либо библиотеке, которую вы не создали.
  • Для примитивных типов. Int, Float, String и т. Д.

Другой причиной использования функции расширения является то, что вам не нужно расширять этот класс, чтобы использовать методы, как если бы они принадлежали этому классу (но фактически не принадлежали этому классу).

Надеюсь, вам будет немного ясно.