2014-07-19 14 views
9

Per caso mi sono imbattuto in sintassi strano compilazione Scala:class Scala estende {}

class Some extends { 
    def hi = println("hi") 
} 

Ragazzi:

  • E 'una Scala ufficiale supportato sintassi?
  • Significa semplicemente estendere lo Object?
  • Si riferisce in qualche modo a "digitazione anatra"?
  • Conosci usi interessanti o complicati di questo?

Grazie.

risposta

4

Questa è in realtà una stranezza nella sintassi di Scala. È consentito un extends estraneo prima di iniziare il corpo della classe. Qui ci sono le parti rilevanti del Scala Syntax Summary:

ClassDef   ::= id [TypeParamClause] {ConstrAnnotation} [AccessModifier] 
         ClassParamClauses ClassTemplateOpt 
ClassTemplateOpt ::= ‘extends’ ClassTemplate | [[‘extends’] TemplateBody] 
ClassTemplate  ::= [EarlyDefs] ClassParents [TemplateBody] 

ClassTemplateOpt è tutto ciò che segue i parametri della classe, in questo caso tutto da extends in poi. L'uso normale di extends è la prima alternanza di ClassTemplateOpt, con extends seguita da un genitore o da un inizializzatore anticipato. Tuttavia, un inizializzatore non può contenere uno def e non è possibile interpretare il contenuto delle parentesi come genitore. Non può essere un tipo strutturale perché hi ha una definizione concreta.

La seconda alternanza consente ai parametri della classe di essere immediatamente seguiti dal corpo della classe, senza utilizzare extends. Tuttavia, è consentito un extends opzionale. Il extends nel codice di OP è un esempio di questo, ed è esattamente equivalente allo stesso codice senza opzionale estende:

class Some { 
    def hi = println("hi") 
} 
-1

Sì, questa è la tipizzazione strutturale di Scala o più comunemente nota come digitazione anatra.

object LoudDuck { 
    def quack(): String = "QUACK" 
} 

object QuietDuck { 
    def quack(): String = "quack" 
} 

object CowDuck { 
    def quack(): String = "moo" 
} 

def quackMyDuck(duck: { def quack(): String }) { 
    println(duck.quack()) 
} 

scala>quackMyDuck(LoudDuck) 
QUACK 

scala> 

scala>quackMyDuck(QuietDuck) 
quack 

scala> 

scala>quackMyDuck(CowDuck) 
moo 

È anche possibile dichiarare i tipi di personale con la parola chiave "tipo".

type Duck = { def quack(): String } 

def quackMyDuck(duck: Duck) { 
    println(duck.quack()) 
} 
+2

Gli esempi forniscono _sono_ digitazione strutturale, ma quello in questione non è. –

+2

Considera 'type T = {def hi = println (" hi ")}' - non viene compilato, perché i tipi strutturali non possono avere definizioni. – wingedsubmariner

4

Questo è in realtà solo un incidente sintattico (credo). Scala consente early definitions che sembrano

class Some extends { 
    ... 
} with ATrait 

in modo che il parser accetta anche class Some extends { ... } che equivale a class Some { ... }(source).

+2

Sembra che le definizioni pre-inizializzate/anticipate non permettano di dichiarare le funzioni. Compilando quanto segue non si compila: tratto ATrait; la classe Alcuni estende {def hi = println ("ciao")} con ATrait – Karl