【发布时间】:2015-07-23 08:48:53
【问题描述】:
(注意:这样做的动机需要冗长而困难的解释;您可以在Accord issue 上找到完整的讨论。它甚至可能不是解决问题的正确方法,但我相信这个问题本身就很有趣。)
我正在寻找一种实现二元运算符的方法,以便其行为取决于右侧操作数的 type:如果它与左侧操作数相同,则为一个行为,否则不同的行为。举个例子:
implicit class Extend[T](lhs: T) {
def testAgainst(rhs: T) = println("same type")
def testAgainst[U](rhs: U) = println("different type")
}
第一个重载比第二个重载更具体,因此您会期望像5 testAgainst 10 这样的调用会触发第一个重载,而5 testAgainst "abcd" 会调用第二个重载。虽然这在理论上是有道理的,但这不会编译,因为擦除的签名对于两个重载都是相同的。
我已经设法以一种需要向第一个重载添加类型参数的方式解决这个问题,但这正是我想要避免的。一个不同的解决方案是修改泛型重载以要求编译器证明类型之间没有子类型关系(与 =:= 相反,遗憾的是 Scala 库没有提供)。
虽然在 Scala 中对子类型关系进行编码通常很容易,但我发现没有办法对其中的缺少进行编码。有没有办法要求第二个重载在编译时成为候选对象,T <:< U 或 T >:> U 都不正确?
【问题讨论】: