繁体   English   中英

Scala-构造函数中的抽象类型

[英]Scala - Abstract type in constructors

考虑以下代码:

sealed trait SpecieType
case class Mammal() extends SpecieType
case class Insect() extends SpecieType

abstract class Specie(name: String, specie: T) {
  type T <: SpecieType
}

但是,由于抽象类型是在Specie类定义中定义的,因此无法编译(第5行)。

要进行这项工作,我需要更改什么?

之所以需要抽象类型,是因为我在编译时需要其参数的类型(以对typeclass模式执行隐式查找)。 基本上,我需要做这样的事情: implicitly[SomeTypeClass[Specie#T]] ,其中SomeTypeClassSomeTypeClass所有子类SpecieType实现的类型类。

不幸的是,这是作为构造函数的类主体造成严重限制的情况之一。 您要实现的目标本身是不可能的。

据我所知,主要有两种选择。 正如@cchantep在评论中所建议的那样,一种方法是使用类型参数而不是抽象类型成员。 需要注意的是,它更改了Specie的声明,这可能会使您的生活在程序的其余部分中变得乏味。

另一种选择是允许您保留类型成员版本,但要付出一些不安全的代价。 这可能是可以接受的,因为无论如何您都有一个抽象类,因此只有子类需要小心:

sealed abstract class Specie(name: String, _specie: SpecieType) {
  type T <: SpecieType

  val specie: T = _specie.asInstanceOf[T]
}

class MammalSpecie extends Specie("Mammal", Mammal()) {
  type T = Mammal
}

如果可以忍受使用中间抽象类丑化Specie子类的定义,则可以增强安全性:

sealed abstract class Specie(name: String, _specie: SpecieType) {
  type T <: SpecieType

  val specie: T = _specie.asInstanceOf[T]
}

abstract class SpecieBase[U <: SpecieType](name: String, _specie: U)
    extends Specie(name, _specie) {
  type T = U
}

class MammalSpecie extends SpecieBase("Mammal", Mammal())

由于Specie本身是密封的,因此从Specie扩展的唯一方法是实际上从没有密封的SpecieBase扩展。 SpecieBaseSpecie无法自身实施的安全性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM