Любой способ для generi c type T для 2 параметров, принудительно использующих один и тот же тип? - PullRequest
3 голосов
/ 11 февраля 2020

Я хочу написать такую ​​функцию, где T должен иметь одинаковый тип данных для обеих переменных, но может быть любым, если они одинаковые.

fun <T> doSomething(var1: T, var2: T) {}

Когда я пишу это , он будет работать с любыми двумя переменными, такими как

doSomething(5, listOf<Thread>())

В настоящее время предполагается, что предполагается, что поскольку int и list различны, T теперь считается Any?

Есть ли какие-либо способ сделать эту работу? Коллега использует Swift, и он работает, как и ожидалось, не в состоянии скомпилировать, если какой-либо элемент имеет другой тип.

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

EG

inline fun <reified T> doSomething(var1: T, var2: T) { }

doSomething(1,"2") <-- unwanted compile
doSomething<String>(1,"2") <-- Will not compile

Но я не хочу иметь только функция работает, если человек не забывает добавить явный тип к ней ...

Ответы [ 2 ]

2 голосов
/ 11 февраля 2020

Похоже, что ваш коллега добавляет ограничения связанного типа. Kotlin не имеет связанных типов, но это может быть похоже на указание вашей Kotlin функции с помощью чего-то вроде этого:

fun <T> doSomething(var1: Comparable<T>, var2: Comparable<T>)

, который в Kotlin будет обеспечивать тот же тип для примитивов, для экземпляр doSomething(3, 4). doSomething(4, "x") не удастся скомпилировать, поскольку оба аргумента не реализуют Comparable одного и того же типа.

Если вам также нужно обрабатывать коллекции, вы можете перегрузить функцию:

fun <T> doSomething(var1: Iterable<Comparable<T>>, var2: Iterable<Comparable<T>>)

Это, вероятно, охватывает большинство случаев использования, которые вы описали в комментариях.

1 голос
/ 11 февраля 2020

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

fun <T> doSomething(var1: T) = fun(var2: T) {
  println("Hello $var1 and $var2")
}

fun te() {
  doSomething(42)("Text") // Error
  doSomething(42)(78) // OK
}

Вы также можете легко расширить его:

fun <T> doSomething(var1: T) = fun(var2: T) = fun(var3: T) {
  println("Hello $var1 and $var2 and $var3")
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...