Разница между закрытой функцией расширения верхнего уровня и закрытой функцией расширения внутри класса

В настоящее время мы переключаем наш проект на Kotlin и натолкнулись на следующий вопрос:

Нам нужна определенная функция расширения только внутри данного класса. Таким образом, у нас есть две возможности: (1) Объявление функции расширения. private на файл верхнего уровня или (2) объявление функции расширения private внутри класса.

После MCVE:

Пример верхнего уровня (файл C1.kt):

private fun String.double() = this.repeat(2)
class C1 {
    init {
        println("init".double())
    }
}

Пример внутри класса (файл C2.kt):

class C2 {
    private fun String.double() = this.repeat(2)
    init {
        println("init".double())
    }
}

Вопросы:

  1. Есть ли разница в этих двух подходах, кроме того, что в C1.kt функция расширения String.double() также будет виден другим возможным членам файла (например, дополнительные классы в том же файле)?

  2. Поскольку мы хотим создать код "как можно более котлиническим", нам хотелось бы знать, какой из двух подходов является предложенным. Есть ли официальное предложение / руководство по стилю на приведенном выше примере? Я думаю, что считается хорошей практикой объявлять функции расширения как можно ближе к их предполагаемому использованию, поэтому в приведенном выше примере структура C2 будет предложено?

1 ответ

Решение
  1. Есть ли разница в этих двух подходах, кроме того, что в C1.kt функция расширения String.double() также будет виден другим возможным членам файла (например, дополнительные классы в том же файле)?

Есть одно отличие: при указании функции расширения внутри класса (в вашем примере C2), то у вас дополнительно есть доступ к экземпляру этого класса с квалифицированным this синтаксис (в вашем примере this@C2).

  1. Поскольку мы хотим создать код "как можно более котлиническим", нам хотелось бы знать, какой из двух подходов является предложенным. Есть ли официальное предложение / руководство по стилю на приведенном выше примере? Я думаю, что считается хорошей практикой объявлять функции расширения как можно ближе к их предполагаемому использованию, поэтому в приведенном выше примере структура C2 будет предложено?

Это хороший вопрос. Лично я бы поставил функции расширения вне класса, поскольку они (обычно) задают поведение, относящееся к расширенному типу, а не к типу класса, в котором они используются. Однако, если вам нужна информация, связанная с классом, в функции расширения, я бы затем указал ее внутри класса.

Другие вопросы по тегам