【问题标题】:scala typing require implicitscala 类型需要隐式
【发布时间】:2016-08-02 20:46:41
【问题描述】:

我正在尝试构建以下内容

我有一个父泛型类

abstract class ResultProvider[+T: Writes](db: DB) {
  def get(id: Long): Future[Seq[T]]
}

还有一些实现,例如

class LengthProvider(db: DB) extends ResultProvider[LengthResult](db){
  override def get (userId: Long): Future[Seq[LengthResult]] = ...
}

object LengthProvider extends ((DB) => DisciplinePredictor) {
  override def apply(db: DB) = new LengthProvider(db)
}

我有以下配置图:

val providers: Map[String, ((DB) => ResultProvider[???])] = Map(
  "length" -> LengthProvider,
  "width"  -> WidthProvider,
   ...
)

我的问题是我应该用什么代替???。理想情况下,它应该类似于T : Writes,因为我只关心这种类型是否实现了Writes 隐式实现,因为我将使用Json.toJson 它。它将使用Any 进行编译,但是该类应该实现Writes 隐式的信息丢失了。 还是我应该使用不同的方法?我可能可以为我所有的结果案例类创建一个超类(例如LengthResult),但我想摆脱隐含。

【问题讨论】:

  • @AlexanderArendar 这根本不是我们想要的。

标签: scala playframework playframework-2.0 scala-implicits


【解决方案1】:

你应该可以写ResultProvider[_](如果你不熟悉这种语法,请搜索“existential types”),但你需要给隐式命名:

abstract class ResultProvider[+T](db: DB)(implicit val writes: Writes[T]) { ... }

其他地方:

val provider: ResultProvider[_] = providers("length")
import provider.writes // makes the implicit visible here
...

您可能需要通过提供类型变量来帮助编译器(或您自己,如果您需要命名类型):

providers("length") match {
  case provider: ResultProvider[a] =>
    import provider.writes 
    ...
}

【讨论】:

  • 成功了!您能否详细说明为什么我需要使用类型变量(即a)来帮助编译器?否则它不起作用。
  • 不幸的是,这取决于我不理解的编译器类型推断的细节。我以前也遇到过类似的情况。
猜你喜欢
  • 1970-01-01
  • 2018-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-29
  • 1970-01-01
  • 2016-10-21
相关资源
最近更新 更多