来自 TreeNode 的定义在 Spark SQL 中:
abstract class TreeNode[BaseType <: TreeNode[BaseType]] extends Product {
self: BaseType =>
...
}
它对 TreeNode
和 BaseType
的子类型有何说明?什么是可以接受的?
最佳答案
self 类型
首先,看一下所谓的 self 类型:Andrew Rollins 的博客对 Self Type Annotations vs. Inheritance 做了很好的介绍。 .
基本上是一个 self 类型,写为
trait Foo { self: SomeType =>
...
}
说,特征 Foo
只能混合在也实现 SomeType
的类中。继承和 self 类型之间的区别也得到了很好的解释here .
self 类型通常用于 Dependency Injection ,例如 Cake Pattern .
类型限制
给定类型定义:
class TreeNode[BaseType <: TreeNode[BaseType]] {
self: BaseType with Product =>
// ...
}
定义
TreeNode[BaseType <: TreeNode[BaseType]]
说: TreeNode 的类型为类型参数BaseType
至少(在子分类的意义上)也是TreeNode[BaseType]
。粗略地说,这意味着:类型参数也必须是TreeNode
本身。这里的 self 类型要求
TreeNode
的子类仅当它还提供Product
时才“允许” 。
具体示例
示例 1
class IntTreeNode extends TreeNode[Int] {}
无法编译,原因是:
- 类型参数
Int
不符合类TreeNode
的类型参数界限,即[BaseType <: TreeNode[BaseType]]
- 由于自身类型限制而导致非法继承。
示例 2
class IntTreeNode2 extends TreeNode[IntTreeNode2]
无法编译,原因是:
- 由于自身类型限制而导致非法继承。
示例 3
class TupleTreeNode extends TreeNode[TupleTreeNode] with Product1[Int] {
// implementation just to be a `Product1`
override def _1: Int = ???
override def canEqual(that: Any): Boolean = ???
}
确实编译,因为:
BaseType
上的类型约束和 self 型都满足。所以,这就是原始定义所要求的。
备注
docs.scala-lang.org 上还给出了与您的示例(Catalyst)类似的示例。
关于scala - 如何解释Spark的TreeNode中的TreeNode类型限制和自类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33062753/