Scala 类型上限允许子类型,但不允许父类型
是否可能有一个泛型方法,其类型绑定相当于“这个特性的每个可能的具体子类,但不是特性本身?” 例如,假设我有以下继承层次结构:Scala 类型上限允许子类型,但不允许父类型,scala,generics,polymorphism,type-bounds,Scala,Generics,Polymorphism,Type Bounds,是否可能有一个泛型方法,其类型绑定相当于“这个特性的每个可能的具体子类,但不是特性本身?” 例如,假设我有以下继承层次结构: sealed trait Fruit case class Apple() extends Fruit case class Orange() extends Fruit ... case class Watermelon() extends Fruit 我想定义一个方法defeatfruit[T我们可以将上限指令与类型不等的自定义隐式强制结合起来。(或通常参见:):
sealed trait Fruit
case class Apple() extends Fruit
case class Orange() extends Fruit
...
case class Watermelon() extends Fruit
我想定义一个方法
defeatfruit[T我们可以将上限指令与类型不等的自定义隐式强制结合起来。(或通常参见:):
然后我们做:
def eatFruit[T <: Fruit](implicit ev: T =!= Fruit) = ???
我们得到:
Error:(29, 13) Cannot prove that yuval.tests.FooBar.Fruit =!= yuval.tests.FooBar.Fruit.
eatFruit[Fruit]
但这包括:
eatFruit[Orange]
这里所有的神奇之处都是由于在对[A,A]
的作用域中创建隐式的歧义,因此编译器会抱怨
我们还可以更进一步,实现我们自己的逻辑类型,例如,让我们称之为=好吧,使用模糊隐式强制类型不平等是某种邪恶的天才。也就是说,虽然这回答了我的问题,但我想指出,这只适用于我指定泛型类型的情况——在我的示例中,如果我编写eatFruit(列表(苹果(),橙色())
让编译器解析泛型类型,它仍然可以编译。不确定原因-可能与这两个通用超类型实际上是可序列化产品的结果有关。
?刚刚验证了这一点-如果您有一个密封特性,其中所有继承对象都是case类,那么您还需要添加隐式=!=
带有可序列化产品的水果的参数。
Error:(29, 13) Cannot prove that yuval.tests.FooBar.Fruit =!= yuval.tests.FooBar.Fruit.
eatFruit[Fruit]
eatFruit[Orange]
@annotation.implicitNotFound(msg = "Cannot prove that ${A} =<:=!= ${B}.")
trait =<:=!=[A,B]
object =<:=!= {
class Impl[A, B]
object Impl {
implicit def subtypeneq[B, A <: B] : A Impl B = null
implicit def subneqAmbig1[A] : A Impl A = null
implicit def subneqAmbig2[A] : A Impl A = null
}
implicit def foo[A, B](implicit e: A Impl B): A =<:=!= B = null
}
case class Blue()
def main(args: Array[String]): Unit = {
eatFruit[Fruit] // Doesn't compile
eatFruit[Blue] // Doesn't compile
eatFruit[Orange] // Compiles
}