Probably I am missing something fundamental here, but I was refactoring certain things in my code and on the halfway I noticed that my code compiles, where I would expect it would not. So here is the method signature:
def checkUiFieldValue[T](fieldName:String, uiValue:T, expectedValue:T):Unit ={...}
Here is a place where it is used:
checkUiFieldValue("State", stateInListView(ar.name), ar.state)
The return type of the stateInListView
is ARState
class, while the type of the ar.state
is String
.
So question is why does it compile and does not tell me that types do not match? I caught myself with a thought that I expect that compiler would check that uiValue
and expectedValue
are of the same type T
but probably my assumption is incorrect.
Or type parameter T
in the method definition actually means that both arguments will be casted to Any
in my case? If so then how should I properly restrict both args to have the same type at compile time?
One possible approach is to infer the types of the two arguments separately then use =:=
to prove they're the same:
def test2[S, T](a: String, b: S, c: T)(implicit ev: S =:= T): T = ???
val x = test2("", new A, new A) // compiles
val y = test2("", new A, new B) // doesn't compile; can't prove A =:= B
This might be a bit strict for you though in the presence of subtyping:
class C extends B
val z = test2("", new B, new C) // doesn't compile; can't prove B =:= C
val w = test2[B, B]("", new B, new C) // does compile
As you mention, the reason why that compiles is that T
is the first common type between stateInListView(ar.name)
and ar.state
.
You can verify this by executing these lines:
class A()
class B()
def test[T](a : String, b : T, c : T) : T = ???
val x : Any = test("ciao", new A(), new B()) // Compiles OK
val y : A = test[A]("ciao", new A(), new B()) // Does not compile: B does not work
val z : B = test[B]("ciao", new A(), new B()) // Does not compile: A does not work
Besides specifying T
manually (e.g. test[A](...)
), I can't really think of a way to avoid this behaviour....
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With