如何让编译器检查2个方法参数是否具有相同的类型?

时间:2017-09-20 12:49:32

标签: scala

可能我在这里缺少一些基本的东西,但我在我的代码中重构了某些东西,并且在中途我注意到我的代码编译,我希望它不会。 所以这是方法签名:

def checkUiFieldValue[T](fieldName:String, uiValue:T, expectedValue:T):Unit ={...}

这是一个使用它的地方:

checkUiFieldValue("State", stateInListView(ar.name), ar.state)

stateInListView的返回类型为ARState类,而ar.state的类型为String。 所以问题是它为什么编译而不告诉我类型不匹配?我发现自己认为编译器会检查uiValueexpectedValue是否属于同一类型T,但可能我的假设不正确。

或者方法定义中的类型参数T实际上意味着在我的情况下两个参数都将被转换为Any?如果是这样,那么我应该如何在编译时正确地将两个args限制为具有相同的类型?

2 个答案:

答案 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)

正如您所提到的,编译的原因是TstateInListView(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](...))之外,我无法想到避免此行为的方法....