简体   繁体   English

Scala抽象类实例

[英]Scala abstract class instance

I am new to Scala. 我是Scala的新手。 I have question about List class. 我对列表类有疑问。 This is an abstract and sealed class. 这是一个抽象的密封类。 It means cannot be instantiated, neither extended. 这意味着无法实例化,也不能扩展。 So what is its usage? 那么它的用途是什么? How can it be that something like following works? 像以下这样的东西怎么会起作用?

val myList = List(1,2,3)

Would myList be a reference to the List object isntance? myList是对List对象的引用的引用吗? Also, if productElement is an abstract method how can that be implemented? 另外,如果productElement是抽象方法,那么如何实现呢?

thanks. 谢谢。

sealed means it cannot be extended outside the file where it is defined. sealed意味着无法将其扩展到定义它的文件之外。 List is sealed but it does have 2 non-abstract sub-classes defined in the same file: Nil and :: representing an empty list an a non-empty list respectively. List是sealed但确实在同一文件中定义了2个非抽象子类: Nil::代表一个空列表和一个非空列表。

When you call List(1,2,3) you're not really instantiating the List class directly. 当您调用List(1,2,3)您实际上并没有直接实例化List类。 It is syntax sugar for List.apply(1, 2, 3) which is calling the apply method on the List object (companion to the List class). 它是List.apply(1, 2, 3) )的语法糖,它在List对象(与List类相对应)上调用apply方法。 And that method is (technically through some indirection) eventually producing an instance of either Nil or :: . 该方法(从技术上讲是通过某种间接方式)最终生成Nil::的实例。

You can see the list sub-classes here: https://github.com/scala/scala/blob/2.13.x/src/library/scala/collection/immutable/List.scala#L547 https://github.com/scala/scala/blob/2.13.x/src/library/scala/collection/immutable/List.scala#L554 您可以在此处查看列表子类: https : //github.com/scala/scala/blob/2.13.x/src/library/scala/collection/immutable/List.scala#L547 https://github.com /scala/scala/blob/2.13.x/src/library/scala/collection/immutable/List.scala#L554

You don't need to implement productElement it is created by the scala compiler for all case classes. 你并不需要实现productElement它是由Scala编译器为所有情况下类创建。

Regarding: 关于:

val myList = List(1,2,3)

When the compiler encounters an expression which creates a class instance without the new modifier, it looks up that classes companion object to look for a .apply method. 当编译器遇到一个表达式,该表达式创建了不带new修饰符的类实例时,它将查找类的伴随对象以寻找.apply方法。 In the case of list, it is defined as: 对于列表,其定义为:

override def apply[A](xs: A*): List[A] = xs.toList

Thus, this compiles successfully. 因此,此编译成功。 You can view this when asking the compiler to emit type information after the typer phase: 当要求编译器在typer阶段之后发出类型信息时,可以查看以下内容:

def main(args: Array[String]): Unit = {
  val l: List[Int] = scala.collection.immutable.List.apply[Int](1, 2, 3);
  ()
}

Would myList be a reference to the List object isntance? myList是对List对象的引用的引用吗?

The run-time type of myList would be either a cons ( :: ) or the empty list ( Nil ). 的运行时类型myList会或者是缺点( :: )或空列表( Nil )。

if productElement is an abstract method how can that be implemented? 如果productElement是抽象方法,那么如何实现?

This is a compiler trick. 这是一个编译器技巧。 productElement and productArity (and more) are both generated at compile time for any case class definition. productElementproductArity (以及更多)都在编译时针对任何case类定义生成。 For example, given the following case class: 例如,给定以下案例类:

case class Bar(i: Int)

The compiler generates: 编译器生成:

// an incomplete view of the generated case class methods and fields
// omitted for brevity.
case class Bar extends AnyRef with Product with Serializable {
  <caseaccessor> <paramaccessor> private[this] val i: Int = _;
  <stable> <caseaccessor> <accessor> <paramaccessor> def i: Int = Bar.this.i;
  def <init>(i: Int): yuval.tests.Foo.Bar = {
    Bar.super.<init>();
    ()
  };
  <synthetic> def copy(i: Int = i): yuval.tests.Foo.Bar = new Bar(i);
  <synthetic> def copy$default$1: Int = Bar.this.i;
  override <synthetic> def productPrefix: String = "Bar";

  // this is the relevant part to your question
  <synthetic> def productArity: Int = 1;
  <synthetic> def productElement(x$1: Int): Any = x$1 match {
    case 0 => Bar.this.i
    case _ => throw new IndexOutOfBoundsException(x$1.toString())
  };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM