Ben987654
Ben987654

Reputation: 3572

Any way for generic type T for 2 parameters forcing the same type?

I want to write a function like this, where T must be the same data-type for both variables, but can be anything as long as they are the same.

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

When I write this, it will work with any two variables, such as

doSomething(5, listOf<Thread>())

The current assumption is it assumes that since int and list are different, that T is now considered Any?

Is there any way to make this work? A coworker is using Swift and it works as expected for him, failing to compile if either item is a different type.

I tried using reified functions as well, but same problem. It only causes a compile error if I explicitly added the reified class at the start, it just assumes it's any otherwise.

E.G.

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

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

But I don't want to only have the function work if the person remembers to add the explicit type on it...

Upvotes: 4

Views: 638

Answers (2)

Tenfour04
Tenfour04

Reputation: 93511

Sounds like maybe your coworker is adding associated type constraints. Kotlin doesn't have associated types, but it might be similar to specifying your Kotlin function with something like this:

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

which in Kotlin would enforce the same type for primitives, for instance doSomething(3, 4). doSomething(4, "x") would fail to compile because the arguments do not both implement a Comparable of the same type.

If you also need to handle collections, you can overload the function:

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

This probably covers most of the use cases you described in the comments.

Upvotes: 2

xinaiz
xinaiz

Reputation: 7788

I don't like comparable approach because it won't work for all types. I think this will do the trick, although has strange syntax:

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

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

You can also easily expand it:

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

Upvotes: 1

Related Questions