Котлин: как передать коллекцию в универсальный тип функции - PullRequest
2 голосов
/ 26 марта 2019

У меня есть эта абстрактная функция:

    abstract fun <T> updateValue(value: T)

Теперь я хочу, чтобы подкласс переопределил его коллекцией в общий тип:

override fun <List<Int>> updateValue(value: List<Int>)

, и это не работает.Базовые типы работают очень хорошо (String, Int и т. Д.), Но когда я хочу использовать коллекцию, я не знаю правильный синтаксис.Это нормально:

override fun <String> updateValue(value: String)

Ответы [ 2 ]

5 голосов
/ 26 марта 2019

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

abstract class BaseClass<T> {
  abstract fun updateValue(value: T) : Unit
}

///class to accept _only_ List<Int>
class ListClass<List<Int>> {
  override fun updateValue(value: List<Int>) { /*...*/ }
}

/// class to accept _only_ String
class StringClass<String> {
  override fun updateValue(value: String) { /*...*/ }
}

Объяснение заключается в следующем, когда вы объявляете обобщенную функцию, например, fun <T> updateValue(value: T) означает, что он должен работать для всех возможных T. Он не будет выполнять сопоставление с образцом, чтобы найти наиболее подходящее совпадение.

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

fun <T> updateValue(value: T) {
  when (value) {
    is String -> handleStringValue(value)
    is List<*> -> handleListValue(value)
    else -> handleDefault(value)
  }
}

Вы не можете отличить List<Int> от List<String> здесь. inline fun с reified генериками может помочь .

3 голосов
/ 26 марта 2019

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

abstract class Parent<T> {
    abstract fun updateValue(value: T)
}

А затем расширить его до:

class Child : Parent<List<Int>> {
    override fun updateValue(value: List<Int>)
}

Единственная причина, по которой переопределение с String работает

override fun <String> updateValue(value: String)

означает, что String не является типом в этом контексте, а является именем универсального параметра, который вы использовали для присвоения T ранее. List<Int> однако недопустимое имя.

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