I came across a piece of code in our codebase, which looked invalid to me, but compiled successfully and worked.
object Main extends {
def main(args: Array[String]): Unit = {
print("Hello World")
}
}
Hello World
Can someone explain me, what happens here?
Does Main
class extend here an anonymous class
/trait
?
If we decompile the code using scala -Xprint:typer
, we see that Main
extends AnyRef
:
scalac -Xprint:typer Main.scala
[[syntax trees at end of typer]] // Main.scala
package com.yuvalitzchakov {
object Main extends scala.AnyRef {
def <init>(): com.yuvalitzchakov.Main.type = {
Main.super.<init>();
()
};
def main(args: Array[String]): Unit = scala.Predef.print("Hello World")
}
}
This is also documented in the Scala specification under object/class definition:
An object definition defines a single object of a new class. Its most general form is
object m extends t
. Here,m
is the name of the object to be defined, andt
is a template of the form
sc with mt1 with … with mtn { stats }
which defines the base classes, behavior and initial state of m. The extends clauseextends sc with mt1 with … with mtn
can be omitted, in which case extends scala.AnyRef is assumed.
This syntax is also valid for early initializers:
abstract class X {
val name: String
val size = name.size
}
class Y extends {
val name = "class Y"
} with X
It desugars into
object Main extends Object
You can check this by compiling with scalac -print
.
Grammar states
ClassTemplateOpt ::= ‘extends’ ClassTemplate | [[‘extends’] TemplateBody]
where
TemplateBody ::= [nl] ‘{’ [SelfType] TemplateStat {semi TemplateStat} ‘}’
so it does seem to be specified as valid if we examine [[‘extends’] TemplateBody]
, as far as I understand.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With