如何证明两种类型在Scala中没有子类型关系?
发布时间:2020-12-16 19:08:33 所属栏目:安全 来源:网络整理
导读:(注意:这个动机需要漫长而艰苦的解释;你可以在这个 Accord issue上找到全面的讨论.它可能不是解决这个问题的正确方法,但我认为这个问题本身很有趣.) 我正在寻找一种实现二元运算符的方式,使得行为取决于右侧操作数的类型:如果与左侧操作数相同,则表现出一
(注意:这个动机需要漫长而艰苦的解释;你可以在这个
Accord issue上找到全面的讨论.它可能不是解决这个问题的正确方法,但我认为这个问题本身很有趣.)
我正在寻找一种实现二元运算符的方式,使得行为取决于右侧操作数的类型:如果与左侧操作数相同,则表现出一种行为,否则不同的行为.举个例子: 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是真的吗 解决方法
如果要强制这两种类型在编译时严格不同,那么
this is the question就可以了.使用定义=!=的一个答案,我们可以想象出多种方法,如下所示:
implicit class Extend[T](lhs: T) { def testAgainst(rhs: T) = println("same type") def testAgainst[U](rhs: U)(implicit ev: T =!= U) = println("different type") } 我们也可以使用TypeTag在一个方法中进行类型测试. import scala.reflect.runtime.universe._ implicit class Extend[T: TypeTag](lhs: T) { def testAgainst[U: TypeTag](rhs: U): Boolean = typeOf[T] =:= typeOf[U] } 你当然可以修改它来分支行为. scala> 1 testAgainst 2 res98: Boolean = true scala> 1 testAgainst "a" res99: Boolean = false scala> List(1,2,3) testAgainst List(true,false) res100: Boolean = false scala> List(1,2) testAgainst List.empty[Int] res102: Boolean = true (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |