多态Scala返回类型

多态Scala返回类型,scala,generics,polymorphism,return-type,Scala,Generics,Polymorphism,Return Type,我有一个抽象的Scala类Base,它有子类Derived1和Derived2Base定义一个函数f(),该函数返回与其实现类相同类型的对象。因此Derived1.f()返回Derived1和Derived2.f()返回Derived2。如何在Scala中编写此代码 以下是我到目前为止的想法 package com.github.wpm.cancan abstract class Base { def f[C <: Base]: C } case class Derived1(x:

我有一个抽象的Scala类
Base
,它有子类
Derived1
Derived2
Base
定义一个函数f(),该函数返回与其实现类相同类型的对象。因此
Derived1.f()
返回
Derived1
Derived2.f()
返回
Derived2
。如何在Scala中编写此代码

以下是我到目前为止的想法

package com.github.wpm.cancan

abstract class Base {
  def f[C <: Base]: C
}

case class Derived1(x: Int) extends Base {
  def f[Derived1] = Derived1(x + 1)
}

case class Derived2(x: Int) extends Base {
  def f[Derived2] = Derived2(x + 2)
}

这个错误消息让我感到困惑,因为我认为
com.github.wpm.cancan.Derived1
在这种情况下应该与
Derived1
相同。

Randall Schulz指出了当前代码不起作用的原因之一。不过,您可以通过以下方式获得所需:


trait Base[C只需对Travis Brown的回答(非常好)增加一点精度:这不是
trait Base[C
Derived1
中的
def[Derived1]
不是对
案例类Derived1
的引用,它是
定义f…
的类型参数!我认为您可以在方法上使用
override
关键字来获得所需的内容(但必须去掉类型参数).是使用该语言功能的另一个示例值得指出的是,F-有界多态性的这个特殊实例相对来说被称为奇怪的递归模板/类型模式,用于定义基类型中的函数,其返回值在不同位置的子类型上是多态的-供检查举例来说,枚举的Java定义是类枚举。@不明确:我一直听说它被称为奇怪的循环模板模式,这是一种更为元的模式。我不明白-为什么后一种解决方案只适用于案例类?如果你的
基本
层次结构只有一个级别,它就会起作用(如果它们都是案例类,则为真)
type mismatch;
[error]  found   : com.github.wpm.cancan.Derived1
[error]  required: Derived1
[error]   def f[Derived1] = Derived1(x + 1)

type mismatch;
[error]  found   : com.github.wpm.cancan.Derived2
[error]  required: Derived2
[error]   def f[Derived2] = Derived2(x + 2)
trait Base[C <: Base[C]] { def f: C }

case class Derived1(x: Int) extends Base[Derived1] {
  def f: Derived1 = Derived1(x + 1)
}

case class Derived2(x: Int) extends Base[Derived2] {
  // Note that you don't have to provide the return type here.
  def f = Derived2(x + 2)
}
trait Base[C <: Base[C]] { self: C => 
  def f: C 
}

case class Derived1(x: Int) extends Base[Derived1] {
  def f: Derived1 = Derived1(x + 1)
}
// a Derived2 where f returns Derived1!!
// this won't compile now
case class Derived2(x: Int) extends Base[Derived1] {
  def f = Derived1(x + 2)
}