【问题标题】:Scala type bounds in builder构建器中的 Scala 类型边界
【发布时间】:2018-06-29 18:46:02
【问题描述】:

我想我的问题缩小到以下几点:

trait Thing

case class SpecificThing(i: Int) extends Thing

trait ThingSource[T <: Thing] {
  def  next: T
}

class SpecificThingSource() extends ThingSource[SpecificThing] {
  override def next = SpecificThing(1)
}

object ThingSource {
  def apply[A <: Thing, B <: ThingSource[A]](sourceType: String): B = {
    sourceType match {
      case "specific" => new SpecificThingSource()
    }
  }
}

val a = ThingSource("specific").next

编译器似乎对大部分内容都很满意,除了构建器部分。这里给出了这个错误:

Expression of type SpecificThingSource doesn't conform to the expected type B

我希望SpecificThingThing 类型的子类型,而SpecificThingSourceThingSource[SpecificThing] 类型,没有歧义的余地。我错过了什么?甚至可以以这种方式使用构建器吗?还是有更好的方法来实现我想要的?

【问题讨论】:

  • 基本上没有办法正确实现带有签名def apply[A &lt;: Thing, B &lt;: ThingSource[A]](s: String): B 的方法,因为如果我用apply[AnyThingImpl, Nothing]("foobar") 调用它,它保证产生Nothing 类型的值。那是行不通的。请更详细地描述您试图实现的目标。
  • 我希望 ThingSource 实例化并返回 ThingSource 的子类,具体取决于传入的字符串。

标签: scala types type-bounds bounded-types


【解决方案1】:

如果你想“返回ThingSource”的一个子类,那么你需要存在,而不是通用 em> 量化:

  def apply(sourceType: String)
  : B forSome { type B <: ThingSource[A] forSome { type A <: Thing}} = {
    sourceType match {
      case "specific" => new SpecificThingSource()
    }
  }

可以写成更短的

  def apply(sourceType: String): ThingSource[_] = {
    sourceType match {
      case "specific" => new SpecificThingSource()
    }
  }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-25
    • 1970-01-01
    • 2022-12-09
    • 2021-01-24
    • 2020-07-22
    • 2013-05-31
    • 1970-01-01
    相关资源
    最近更新 更多