【问题标题】:How can I have a typed (specific) factory in a base trait in Scala?如何在 Scala 的基本特征中拥有类型化(特定)工厂?
【发布时间】:2017-10-05 05:42:39
【问题描述】:

这是我想要实现的行为:

trait PathLike {
  val given: String

  def factory[T <: PathLike]( g: String ):T

  def +[T <: PathLike]( part: String ): T = factory(this.given+"/"+part)
}

case class Path( given: String ) extends PathLike {
  def factory[Path]( g: String ) = Path(g)
}
case class NonRelativePath( given: String ) extends PathLike {
  def factory[NonRelativePath]( g: String ) = NonRelativePath(g)
}

我在 PathLike 中有其他使用 + 的函数,因此简单地将 + 函数移动到每个特定案例类中似乎不是一个好的选择。

目前编译器抱怨:

type mismatch;  found   : com.foo.Path  required: Path  Path.scala
type mismatch;  found   : com.foo.NonRelativePath  required: NonRelativePath    Path.scala

为什么会抱怨,因为它分别有 Path/NonRelativePath?如何从 PathLike 中构造正确类型的 PathLike 子代?

【问题讨论】:

    标签: scala


    【解决方案1】:

    您应该使用trait 类型参数而不是method 类型参数,因为它应该应用于实例创建而不是方法应用。

    trait PathLike[T <: PathLike] {
      val given: String
    
      def factory( g: String ):T
    
      def +( part: String ): T = factory(this.given+"/"+part)
    }
    
    case class Path( given: String ) extends PathLike[Path] {
      def factory( g: String ) = Path(g)
    }
    case class NonRelativePath( given: String ) extends PathLike[NonRelativePath] {
      def factory( g: String ) = NonRelativePath(g)
    }
    

    使用def factory[Path]( g: String ) = 您正在为方法类型参数创建一个新名称。有关类型阴影的更多信息,请参阅这些答案:123

    【讨论】:

      【解决方案2】:

      在定义中显式添加返回类型。

      def factory[Path]( g: String ): Path = Path(g)
      

      【讨论】:

        猜你喜欢
        • 2019-04-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-09
        • 2014-10-14
        相关资源
        最近更新 更多