多态Scala返回类型 [英] Polymorphic Scala return type
问题描述
我有一个抽象Scala类 Base ,它有子类
Derived1
和 Derived2
。
Base
定义了一个函数f(),它返回与其实现类相同类型的对象。因此 Derived1.f()
返回 Derived1
和 Derived2.f()
返回 Derived2
。我该如何在Scala中编写它?
这是我到目前为止所提供的。
<$ p $ >
package com.github.wpm.cancan
抽象类Base [
def f [C< Base]:C
}
case class Derived1(x:Int)extends Base {
def f [Derived1] = Derived1(x + 1)
}
case class Derived2( x:Int)扩展Base {
def f [Derived2] = Derived2(x + 2)
}
这给出了下列编译器错误:
type mismatch;
[error] found:com.github.wpm.cancan.Derived1
[error] required:Derived1
[error] def f [Derived1] = Derived1(x + 1)
类型不匹配;
[error] found:com.github.wpm.cancan.Derived2
[error] required:Derived2
[error] def f [Derived2] = Derived2(x + 2)
这个错误信息令我感到困惑,因为我认为 com.github.wpm.cancan。在这种情况下,Derived1
应该与 Derived1
相同。
Randall Schulz指出了你当前的代码不起作用的原因之一。尽管如此,可以通过 F - 有界多态性获得所需内容: p>
trait Base [C<:Base [C]] {def f:C}
案例类Derived1(x:Int)extends Base [Derived1] {
def f:Derived1 = Derived1(x + 1)
}
案例类Derived2(x:Int)extends Base [Derived2] {
//请注意,您不必在此处提供返回类型。
def f = Derived2(x + 2)
}
在基础特征允许你谈论那里的实现类 - 例如在 f
。
的返回类型中
I have an abstract Scala class Base
which has subclasses Derived1
and Derived2
. Base
defines a function f() which returns an object of the same type as its implementing class. So Derived1.f()
returns Derived1
and Derived2.f()
returns Derived2
. How do I write this in Scala?
Here is what I have come up with so far.
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)
}
This gives the following compiler errors:
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)
This error message is confusing to me because I think com.github.wpm.cancan.Derived1
should be the same as Derived1
in this context.
Randall Schulz pointed out one of the reasons your current code doesn't work. It is possible to get what you want, though, with F-bounded polymorphism:
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)
}
The type parameter on the base trait allows you to talk about the implementing class there—e.g. in the return type for f
.
这篇关于多态Scala返回类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!