简体   繁体   English

生成器中的Scala类型范围

[英]Scala type bounds in builder

I think I narrowed my problem down to the following: 我认为我的问题可以归结为以下几点:

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

The compiler seems to be happy about most of it, except for the builder part. 编译器似乎对大多数编译器都很满意,除了生成器部分。 Here it gives this error: 这里给出了这个错误:

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

I would expect that with SpecificThing being a subtype of type Thing , and SpecificThingSource being of type ThingSource[SpecificThing] , there is no room for ambiguity. 我希望在SpecificThingThing类型的子类型,而SpecificThingSourceThingSource[SpecificThing]类型的ThingSource[SpecificThing] ,没有歧义的余地。 What am I missing? 我想念什么? Is it even possible to use a builder in this way? 甚至可以通过这种方式使用构建器吗? Or are there better ways to achieve what I want? 还是有更好的方法来实现我想要的?

If you want to "return a subclass of ThingSource " , then you need existential , not universal quantification: 如果要“返回ThingSource 子类” ,则需要存在的 ,而不是通用的量化:

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

which can be written shorter as 可以写成更短的

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

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

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