【问题标题】:Default generic type on method in scalascala中方法的默认泛型类型
【发布时间】:2015-12-15 03:09:13
【问题描述】:

我正试图找出一种方法来摆脱重载的方法。目前我正在使用这种方法为用户提供漂亮的 API:

  def get(id: String): Option[JsonDocument]

  def get(id: String, timeout: Duration): Option[JsonDocument]

  def get[D <: Document[_]](id: String, target: Class[D]): Option[D]

  def get[D <: Document[_]](id: String, target: Class[D], timeout: Duration): Option[D]

现在由于 scala 具有默认参数,我想将其浓缩为一种方法。但是因为 D 是通用的,如果没有提供,我需要默认值不是“Nothing”,而是“JsonDocument”。

我目前的做法是这样的:

  def get[D <: Document[_]](id: String, target: Class[D] = classOf[JsonDocument], timeout: Duration = null): Option[D]

事实证明编译器对此非常满意,但 IDE 存在问题。如果没有明确提供目标(如 target = JsonDocument 或任何其他),它认为返回类型是 Option[Nothing],因此它会让用户感到困惑。

所以我的问题是:对于这些类型,如果用户没有提供要覆盖的 JsonDocument 类型,是否可以为类型 D 提供“默认”类型?

【问题讨论】:

标签: scala generics


【解决方案1】:

http://www.cakesolutions.net/teamblogs/default-type-parameters-with-implicits-in-scala 给出了默认泛型参数问题的解决方案。应用到您的案例中,您会得到类似(未经测试)的信息:

trait DefaultsTo[Type, Default]

object DefaultsTo {
  implicit def defaultDefaultsTo[T]: DefaultsTo[T, T] = null
  implicit def fallback[T, D]: DefaultsTo[T, D] = null  
}

// use target.runtimeClass in the implementation
def get[D <: Document[_]](id: String, timeout: Duration)(implicit target: scala.reflect.ClassTag[D], default: DefaultsTo[D, JsonDocument]): Option[D]

使用:get(id, timeout) 代表 JsonDocumentget[OtherDocument](id, timeout)。当然,IDE(IntelliJ?)是否会正确推断类型是另一个问题!

【讨论】:

  • 是的,这行得通,但遗憾的是 IntelliJ 也无法正确拾取它。但是感谢您的澄清!
猜你喜欢
  • 1970-01-01
  • 2015-08-21
  • 2017-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-26
  • 2017-09-08
  • 2012-11-01
相关资源
最近更新 更多