可能我在这里缺少一些基本的东西,但我在我的代码中重构了某些东西,并且在中途我注意到我的代码编译,我希望它不会。 所以这是方法签名:
def checkUiFieldValue[T](fieldName:String, uiValue:T, expectedValue:T):Unit ={...}
这是一个使用它的地方:
checkUiFieldValue("State", stateInListView(ar.name), ar.state)
stateInListView
的返回类型为ARState
类,而ar.state
的类型为String
。
所以问题是它为什么编译而不告诉我类型不匹配?我发现自己认为编译器会检查uiValue
和expectedValue
是否属于同一类型T
,但可能我的假设不正确。
或者方法定义中的类型参数T
实际上意味着在我的情况下两个参数都将被转换为Any
?如果是这样,那么我应该如何在编译时正确地将两个args限制为具有相同的类型?
答案 0 :(得分:4)
一种可能的方法是分别推断两个参数的类型,然后使用(decimal)
来证明它们是相同的:
=:=
虽然存在子类型,但这对你来说可能有点严格:
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
答案 1 :(得分:3)
正如您所提到的,编译的原因是T
是stateInListView(ar.name)
和ar.state
之间的第一种常见类型。
您可以通过执行以下行来验证这一点:
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
除了手动指定T
(例如test[A](...)
)之外,我无法想到避免此行为的方法....