2013-08-06 12 views
12

Wegabhängige Typen sind nützlich:Abhängige Typen funktionieren nicht für Konstruktoren?

trait Sys { 
    type Global 
} 
def foo[S <: Sys](system: S)(global: system.Global) =() 

Warum funktioniert diese Arbeit für den Bau?

class Foo[S <: Sys](val system: S)(val global: system.Global) 

Oder mache ich es nur falsch?

+0

Ich habe diesen Satz in der SLS gefunden: * Ein formaler Wertparameter darf jedoch nicht Teil der Typen der übergeordneten Klassen oder Mitglieder der Klassenvorlage t. * (5.3, p56) bezüglich * formal sein Wertparameterklauseln für den primären Konstruktor *. – Beryllium

+4

Workaround: 'Merkmal Foo [S: senia

+0

@senia Ja, ich verwende jetzt eine Eigenschaft, die Konstruktormethode ist zwar ziemlich hässlich, aber es funktioniert. –

Antwort

5

Dies scheint wie ein Fehler für mich. Bearbeiten: gefunden, das ist SI-5712.

Abschnitt § 5.3 des 2.9 SLS sagt:

(ps1). . . (psn) sind formale Wertparameterklauseln für den primären Konstruktor der Klasse. Der Umfang eines Formalwertparameters umfasst alle nachfolgenden Parameterabschnitte und das Template t.

Es gibt eine Ausnahme:

jedoch ein formeller Wertparameter kann nicht Teil der Arten von einem der übergeordneten Klassen oder Mitglieder der Klassenvorlage t bilden.

Aber es sagt, es ist nicht Teil der Arten von jeder der übergeordneten Klassen oder Mitglieder sein, nicht jeder der folgenden Parameter Abschnitte, so dass es nicht scheint nicht wegabhängig Typen zwischen verbieten Argumentgruppen.

Sie können mit einem sekundären Konstruktor, um dieses gehen:

class Foo[S <: Sys] private[this]() { 
    def this(system: S)(global: system.Global) = this 
} 

bearbeiten: Diese sekundären Konstruktor Abhilfe ist nicht sehr gut: Aussetzens system oder global sehr schwierig geworden, weil nur der primäre Konstruktor val s erklären kann .

Ein Beispiel mit einer Besetzung:

class Foo[S <: Sys] private[this]() { 
    private[this] var _system: S = _ 
    private[this] var _global: system.Global = _ 

    def this(system0: S)(global0: system0.Global) = { 
    this 
    _system = system0 
    _global = global0.asInstanceOf[system.Global] 
    } 

    lazy val global: system.Global = _global 
    lazy val system: S = _system 
} 

Aber das ist schrecklich zu bekommen. @ Senias Vorschlag ist viel besser.

+0

Ok. Das Problem mit dem sekundären Konstruktor ist jedoch, dass ich auf diese Weise kein 'Foo' mit einem' def global: system.Global' konstruieren kann (Ich habe es nicht versucht, aber es klingt unmöglich) –

+0

Hum, du Stimmt, es gibt keinen einfachen Weg für 'Foo', diese Werte zu offenbaren. Du brauchst mindestens eine 'var' und eine Besetzung, was ein bisschen traurig ist, siehe Bearbeiten. – gourlaysama

+1

Danke für das Ausgraben des Bugtickets –

Verwandte Themen