Общий тип <T>параметр ПЕРЕД именем функции - PullRequest
0 голосов
/ 26 февраля 2019

Как используется параметр типа <T> перед именем функции в Kotlin?

Пример:

fun <T> MutableList<T>.swap(index1: Int, index2: Int) {
    val tmp = this[index1] 
    this[index1] = this[index2]
    this[index2] = tmp
}

Ссылка на первый <T> выше.

Я пытался просмотреть документы Kotlin относительно дженериков, а также обобщения Java , однако они в основном касаются только 2 <T>не первый.

Ответы [ 5 ]

0 голосов
/ 26 февраля 2019

(Вот другой подход.)

Рассмотрим обычную неуниверсальную функцию:

fun myFun(a: Int, b: String) {
    // …use a and b…
}

Что такое a и b?Они еще ничего не значат.Они просто говорят: «Когда вы вызываете эту функцию, вы должны передать эти значения».Вы ожидаете, что тело функции будет ссылаться на них каким-то образом;вот когда они привыкнут.

Теперь рассмотрим универсальную функцию:

fun <T, U> myFun(/* …use T and U… */) {
    // …
}

То же самое с T и U.Это тоже параметры - type parameters.Как и в случае с параметрами-значениями, объявление параметров типа само по себе ничего не значит, но дает заполнители для типов, которые должны быть переданы (явным образом или выведены) при вызове функции.(Объявление <…> также дает возможность указать любые ограничения или дисперсию, например, <T : Number> или <out T>.) И вы обычно будете использовать эти параметры типа позже - в этом случае, в остальной части сигнатуры функции.

0 голосов
/ 26 февраля 2019

Чтобы добавить к ответу Лино, представьте, что это определение имеет невидимые фигурные скобки после объявления параметра типа:

fun <T> \*{*\ MutableList<T>.swap(index1: Int, index2: Int) {...} \*}*\

Так что это правильно лексически ограничено .Если это <T> идет после имени функции, вы потеряете это свойство, усложните синтаксический анализатор и только сделаете код менее читабельным для людей.

Также было бы сложно запомнить <T> перед именемдля функций расширения, но после него для функций-членов.Достаточно плохо, что это должно быть сделано для классов!

Scala помещает [T] после имени метода, но это потому, что у него совершенно другой синтаксис для функции, соответствующей методам расширения.Scala 3 пойдет на сложный синтаксический анализ , вероятно, потому, что подобный Kotlin синтаксис не будет соответствовать любому другому синтаксису.

0 голосов
/ 26 февраля 2019

"T" представляет общий тип / класс, который вы передаете функции.Ваш вопрос о "Т" при возврате функции.Поэтому предполагается, что вы возвращаете тип / класс в зависимости от того, что вы передаете в функцию.

0 голосов
/ 26 февраля 2019

Первый <T> вводит параметр общего типа в функцию, как вы знаете.Вторая <T> это часть MutableList<T>, приемник функции расширения , которую определяет ваш код: функция расширения определяется как

fun [GenericTypeList] ReceiverType.FunctionName ([ParametersList]) [: ReturnType] {...}

, как вы можете видеть в официальной документации, на которую я ссылался выше. тип получателя - это тип, к которому вы добавляете функцию расширения к ( функциям расширения * синтаксический сахар для чего-то вроде (Java) static вызовы методов).В вашем примере вы добавляете функцию расширения к generic MutableList<T>, поэтому при определении приемника вы предоставляете спецификацию универсального типа (для которой требуется параметр универсального типа * 1031)* представлен первым <T>).

Я надеюсь, что мое объяснение может быть ясным и исчерпывающим для вас!

0 голосов
/ 26 февраля 2019

Используется для указания того, что используются дженерики, а не какой-либо тип T.

Посмотрите на этот вполне допустимый пример

fun <String> MutableList<String>.swap(index1: Int, index2: Int)

Теперь это можно вызывать на любом MutableList<*>, а не только MutableList<String>.Если бы вы не написали <String> после ключевого слова fun, как бы kotlin узнал, что на самом деле вы ссылаетесь на универсальный, а не kotlin.String?

То же самое относится к примеру, который вы показали.<> после fun просто вводит новый универсальный параметр, иначе kotlin будет жаловаться, что не знает тип T

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...