[英]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. productElement
和productArity
(以及更多)都在编译时针对任何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.