Как применить действия к универсальным типам в классе, это работает с универсальными типами - PullRequest
0 голосов
/ 01 марта 2019

Я сейчас пытаюсь выяснить, как работают дженерики.И я нашел этот пример

class SomeGenericClass <T> {

    fun <T> makeSomething(someData : T) : T {
       var localData = someData
       //... doing some actions
       return localData
   }
}

И теперь мне интересно - как мы можем применить некоторые действия к универсальному типу, передаваемому в качестве параметра в метод makeSomething .Это вообще возможно?Можем ли мы применить некоторые действия или изменения к someData (не базовые действия, которые можно выполнить с объектом Any -toString, hashCode).Я думаю, что это невозможно, я прав?Или этот пример:

fun <T> doJob(valOne: T, valTwo: T){

}

Мы не можем применять какие-либо действия к объектам valOne и valTwo.В обоих случаях нам нужно расширить базовый класс или интерфейс и переопределить эти методы?

Ответы [ 2 ]

0 голосов
/ 01 марта 2019

Вопрос в следующем: что вы хотите с ними сделать?

Как написано, единственное, что вы знаете о T, это то, что это какой-то тип - потому что вы неНе знаю , какой тип, вы не можете делать ничего конкретного типа.Таким образом, единственные вещи, которые вы можете делать со значениями типа T, - это вещи, которые работают для всех типов, то есть вещи, которые вы можете делать с Any?.Это включает в себя сравнение их на равенство (или идентичность) с другими типами (или null), преобразование их в String s, сохранение их в коллекциях и т. П.

Для дальнейшегонужно узнать больше о типе T.Если, например, вы знаете, что это CharSequence (например, String), тогда вы можете сообщить компилятору, указав привязку типа, например, <T : CharSequence>.

Затем вы можете сделать что-нибудь сT, что вы можете сделать с CharSequence, например, получить его длину, перебрать или отобразить его символы и т. Д.(согласно ответу zsmb13 ).Тем не менее, компилятор не позволит вам вызывать его с помощью несвязанного класса.

Итак, с обобщениями - как и с любым другим кодом - то, что вы можете сделать с объектом, зависит от того, что вы знаете о его типе.

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

0 голосов
/ 01 марта 2019

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

fun <T : CharSequence> useThing(thing: T) {
    println(thing)
}

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

fun <T> performActions(thing: T, actions: (T) -> Unit) {
    actions(thing)
}

performActions(25) { thing: Int ->
    println(3 * thing) 
}

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

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