Spark的TreeNode中TreeNode的类型限制和自类型怎么解释?

How to explain TreeNode type restriction and self-type in Spark's TreeNode?

从Spark中TreeNode的定义SQL:

abstract class TreeNode[BaseType <: TreeNode[BaseType]] extends Product {
  self: BaseType =>
  ...
}

它对 TreeNodeBaseType 的子类型有什么看法?什么是可以接受的?

自我类型

首先,看看所谓的 自我类型 :Andrew Rollins 的博客在 Self Type Annotations vs. Inheritance.

上给出了一个很好的介绍

基本上是一个self类型,写成

trait Foo { self: SomeType =>
  ...
}

说,特征 Foo 只能混合在 class 中,它也实现了 SomeType。继承和自我类型之间的区别也很好地解释了here

通常,自我类型用于 Dependency Injection, such as in the Cake Pattern

类型限制

给定类型定义:

class TreeNode[BaseType <: TreeNode[BaseType]] {
  self: BaseType with Product =>
  // ...
}
  1. 定义 TreeNode[BaseType <: TreeNode[BaseType]] 说:TreeNode 的类型使得类型参数 BaseType 至少(在 sub-classing 的意义上)也是一个TreeNode[BaseType]。粗略地说,这意味着:类型参数也必须是 TreeNode 本身。

  2. 此处的自我类型要求,TreeNode 的子class 如果还提供Product 则仅是"allowed"。

具体例子

示例 1

class IntTreeNode extends TreeNode[Int] {}

编译由于:

  1. 类型参数 Int 不符合 class TreeNode 的类型参数范围,即 [BaseType <: TreeNode[BaseType]]
  2. 由于自我类型限制导致的非法继承。

示例 2

class IntTreeNode2 extends TreeNode[IntTreeNode2]

编译由于:

  1. 由于自我类型限制导致的非法继承。

示例 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 = ???
}

是否 编译由于:

  1. type constraint on BaseTypeself-type 都满足了。所以,这就是原始定义所要求的。

备注

docs.scala-lang.org

上也给出了一个类似于你的例子 (Catalyst)