obe*_*tie 2 generics scala f-bounded-polymorphism
我在 GitHub 上查看一些代码,发现了这个类型声明:
abstract class TreeNode[BaseType <: TreeNode[BaseType]] extends Product with TreePatternBits {
Run Code Online (Sandbox Code Playgroud)
(这是来自 Spark 源代码,尽管这个问题实际上并不是关于 Spark,而是关于 Scala 的类型系统。)
这对我来说是新的。用简单的英语来说,这种类型绑定是什么意思?
几乎没有人阅读关于 System F 的白皮书(评论中提到),人们仍然直观地使用 F 绑定型多态性。
您需要了解的是,类/特征MyType[A <: MyType[A]]强制您将其扩展为class Impl extends MyType[Impl],即将其自身作为类型参数传递。
trait Interface[A <: Interface[A]] {
def getValue: String
def setValue(value: String): A
}
Run Code Online (Sandbox Code Playgroud)
如果您想做类似的事情,这很有用:
class Impl(value: String) extends Interface[Impl] {
override def getValue: String = value
override def setValue(value: String): Impl = new Impl(value)
}
Run Code Online (Sandbox Code Playgroud)
如果没有这个A <: Interface[A]( typeA是 /extends 的子类型Impl[A]),有人可能会实现:
// no F-bound type polymorphism
trait Interface[A] {
def getValue: String
def setValue(value: String): A
}
class Foo
class Impl extends Inteface[Foo] {
override def getValue: String = value
// we wanted to force implementation to have Impl here but now we cannot
override def setValue(value: String): Foo = new Foo
}
Run Code Online (Sandbox Code Playgroud)
如果您有对一些代数进行建模的接口,例如:
trait Number[A <: Number[A]] {
def add(a: A): A
}
Run Code Online (Sandbox Code Playgroud)
使实现方法的输入/输出与其自身类型相同:
class Integer(val i: Int) extends Number[Integer] {
def add(a: Integer): Integer = new Integer(i + a.i)
}
Run Code Online (Sandbox Code Playgroud)
它在 OOP 中更受欢迎,因为 FP 提供了使用类型类的替代方法。
| 归档时间: |
|
| 查看次数: |
324 次 |
| 最近记录: |