如何在Spark的TreeNode中解释TreeNode类型限制和自我类型?

时间:2015-10-11 07:55:26

标签: scala apache-spark-sql treenode self-type

从Spark SQL中TreeNode的定义:

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

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

1 个答案:

答案 0 :(得分:4)

自类型

首先,看看所谓的自我类型:Andrew Rollins的博客在Self Type Annotations vs. Inheritance上做了一个很好的介绍。

基本上是一种自我类型,写成

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

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

通常,自我类型用于Dependency Injection,例如Cake Pattern

类型的限制

鉴于类型定义:

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

  2. 此处的自我类型要求,如果TreeNode的子类同时提供Product,则class IntTreeNode extends TreeNode[Int] {} 的子类仅被“允许”。

  3. 具体例子

    示例1

    Int

    不会编译,因为:

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

      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. 由于自我限制而导致的非法继承。
      2. 示例3

        BaseType

        编译由于:

          interface a { public show(); } interface b { public show(); } class name implements a,b { private int var = 10; public show() { System.out.print(var); } } 上的
        1. 类型约束自我类型都已完成。所以,这就是原始定义所要求的。
        2. 备注

          docs.scala-lang.org

          上也提供了与您的(Catalyst)类似的示例