在 Scala 中,如何定义排除已定义类的类型上限



给定一个具体的类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)

使用无形可以写:

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

否则,您可以自己为隐式实现类似的类型。

Scala 中类型不等式的类型约束

强制实施类型差异

如何在 Scala 中拥有否定类型?

在 Scala 3 中,这很容易:

import scala.util.NotGiven
class Animal:
  def name: String = "General Animal"
class Dog extends Animal:
  override def name: String = "Dog"
class SpecificAnimalContainer[A <: Animal : [A] =>> NotGiven[A =:= Animal]](a: A):
  def specificAnimal: A = a
val dogContainer = new SpecificAnimalContainer[Dog](new Dog)
// doesn't compile
val animalContainer = new SpecificAnimalContainer[Animal](new Animal)
目前还

不清楚您要实现的目标,但是您的问题看起来与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

希望这有帮助

最新更新