理解Scala 3.3.1中Tuple2类的继承层次结构

1 inheritance scala tuples scala-3

我希望更清楚地理解Scala 3.3.1 中 Tuple2 类的位置。

在其源代码中,可以清楚地看出该类继承了 Product2 特征。我仍然怀疑的是 Tuple2 是如何立即继承自:

  • 类 T1 *: T2 *: EmptyTuple.type
  • 特质可序列化

我一直无法理解这一点。

我已经阅读了相关的 Scala 文档和源代码。我可以理解这些层次结构的继承的整体设计思想,但我还没有理解更细致的点(以问题为例)

Dmy*_*tin 5

我们不要混淆类和类型、继承(子类化)和子类型化

\n

类型和类别有什么区别?

\n

Scala(和 Java)中的类和类型有什么区别?

\n

https://typelevel.org/blog/2017/02/13/more-types-than-classes.html

\n

OO 编程中的子类型和继承有什么区别?

\n

https://counterexamples.org/subtyping-vs-inheritance.html

\n

从OOP的角度来看,Tuple2extends(是)的子类Product2Product2extends Product。并*:延伸NonEmptyTupleNonEmptyTuple延伸。EmptyTupleTuple两个独立的 OOP 层次结构。

\n

创建 的子A *: B *: EmptyTuple类型Tuple2[A, B]反之亦然(并提供语法糖(A, B))是编译器的魔法。根据规范,

\n
\n

元组类型(T1,...,Tn),其中n \xe2\x89\xa5 2是 类型的糖T1 *: ... *: Tn *: scala.EmptyTuple,其本身是一系列嵌套的中缀类型,其中 是 的糖*:[T1\xe2\x80\x8b, *:[T2\xe2\x80\x8b, ... *:[Tn\xe2\x80\x8b, scala.EmptyTuple]]]

\n
\n

https://scala-lang.org/files/archive/spec/3.4/03-types.html#tuple-types

\n
\n

一致性关系是满足以下任一条件时为真的(<:)最小关系。S <: T

\n
    \n
  • ...
  • \n
  • T = scala.Tuple_n\xe2\x80\x8b[T1\xe2\x80\x8b,...,Tn\xe2\x80\x8b]1 \xe2\x89\xa4 n \xe2\x89\xa4 22, 和S <: T1\xe2\x80\x8b *: ... *: Tn\xe2\x80\x8b *: scala.EmptyTuple.
  • \n
\n
\n

https://scala-lang.org/files/archive/spec/3.4/03-types.html#conformance

\n

在编译器中,子类型是在以下位置实现的TypeComparer

\n
  /** Does `tycon` have a field with type `tparam`? Special cased for `scala.*:`\n   *  as that type is artificially added to tuples. */\n  private def typeparamCorrespondsToField(tycon: Type, tparam: TypeParamInfo): Boolean = ...\n
Run Code Online (Sandbox Code Playgroud)\n
    /** Subtype test for the hk application `tp2 = tycon2[args2]`.\n     */\n    def compareAppliedType2(tp2: AppliedType, tycon2: Type, args2: List[Type]): Boolean = {\n      ...\n        case tycon2: TypeRef =>\n          ...\n            tycon2.info match {\n              ...\n              case info2: ClassInfo =>\n                tycon2.name.startsWith("Tuple") &&\n                  defn.isTupleNType(tp2) && recur(tp1, tp2.toNestedPairs) ||\n                tryBaseType(info2.cls)\n
Run Code Online (Sandbox Code Playgroud)\n

https://dotty.epfl.ch/docs/internals/type-system.html#subtyping-checks-1

\n

https://github.com/lampepfl/dotty/blob/main/compiler/src/dotty/tools/dotc/core/TypeComparer.scala

\n

关于Serializable,所有案例类都扩展ProductSerializableTuple2一个案例类。您可以打开scalacOptions ++= Seq("-Vprint:typer", "-Xprint-types") 并查看

\n
case class MyClass(i: Int, s: String)\n\n//    case class MyClass(i: Int, s: String) extends\n//      <<<new Object:Object>:((): Object)>():Object>, Product, Serializable {\n//      ...\n
Run Code Online (Sandbox Code Playgroud)\n

这是在 Scala 2 中为案例类生成糖的解释,但在 Scala 3 中这应该是类似的

\n

如何查看 Scala 用于自动生成案例类的 apply 函数的代码?

\n

(这样就可以找到添加的特定位置extends Serializable)。

\n


归档时间:

查看次数:

56 次

最近记录:

1 年,11 月 前