在Scala中,如何定义不包含已定义类的上限类型?

时间:2018-02-02 20:10:52

标签: scala types

给定一个具体的类Animal,如何定义一个仅占用Animal的子类的函数?

在这样的典型示例中,Animal是一个特征,因此定义[A <: Animal]意味着您已经传入了Animal的子类。但是,在下面Animal具体的情况下,我可以将其排除为允许类型吗?

我正在使用现有的生成代码,这只是问题的一个通用示例。因此,暗示我无法将Animal(或等效物)变成trait

见下面的例子:

class Animal {
  def name: String = "General Animal"
}

class Dog extends Animal {
  override def name: String = "Dog"
}

// How do I limit A to be a subtype of Animal (excluding Animal itself)?
class SpecificAnimalContainer[A <: Animal](a: A) {
  def specificAnimal: A = a
}

val dogContainer = new SpecificAnimalContainer[Dog](new Dog)

// I do not want this to be able to compile.
val animalContainer = new SpecificAnimalContainer[Animal](new Animal)

2 个答案:

答案 0 :(得分:1)

使用无形你可以写:

import shapeless._

class SpecificAnimalContainer[A <: Animal](a: A)(implicit ev: A =:!= Animal) {
  def specificAnimal: A = a
}

//  val animalContainer = new SpecificAnimalContainer[Animal](new Animal)// doesn't compile

否则你可以自己实现类似的隐式类型。

Type constraint for type inequality in scala

Enforce type difference

How can I have a negation type in Scala?

答案 1 :(得分:0)

您要尝试实现的目标有点不清楚,但您的问题看起来与Scala文档中的书籍示例完全相同 https://docs.scala-lang.org/tour/upper-type-bounds.html

abstract class Pet extends Animal {}

class PetContainer[P <: Pet](p: P) {
  def pet: P = p
}

class Lion extends Animal {
  override def name: String = "Lion"
}

//  val lionContainer = new PetContainer[Lion](new Lion)
//                         ^this would not compile

希望这有帮助