2013-08-06 16 views
12

tipi di percorso-dipendenti sono utili:I tipi dipendenti non funzionano per i costruttori?

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

Perché non fa questo lavoro per i costruttori?

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

Oppure sto sbagliando?

+0

Ho trovato questa frase nella SLS: * Tuttavia, un parametro di valore formale non può far parte dei tipi di una qualsiasi delle classi o dei membri principali del modello di classe t. * (5.3, p56) riguardante * formale clausole sui parametri di valore per il costruttore principale *. – Beryllium

+4

Soluzione alternativa: 'trait Foo [S: senia

+0

@senia Sì, sto usando un tratto ora, il metodo di costruzione è piuttosto brutto, ma funziona. –

risposta

5

Questo mi sembra un insetto. Modifica: trovato, questo è SI-5712.

sezione §5.3 del 2,9 SLS dice:

(PS1). . . (psn) sono clausole dei parametri di valore formale per il costruttore principale della classe. L'ambito di un parametro di valore formale include tutte le successive sezioni di parametro e il modello t.

C'è un'eccezione:

Tuttavia, un parametro di valore formale non può far parte dei tipi di una delle classi controllanti o membri della classe template t.

Ma dice che non può essere parte dei tipi di qualsiasi delle classi genitore o membri, non di qualsiasi delle seguenti sezioni di parametri, in modo che non sembra proibire tipi di percorso-dipendente tra gruppi di discussione.

Si può andare in giro questo con un costruttore secondaria:

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

Modifica: questa soluzione costruttore secondario non è molto buona: esponendo system o global diventare molto difficile, perché solo il costruttore principale può dichiarare val s .

Un esempio con un cast:

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 
} 

Ma questo è sempre terribile. Il suggerimento di @ senia è molto meglio.

+0

Ok. Il problema con il costruttore secondario, tuttavia, è che in questo modo non sarò in grado di costruire un 'Foo' con un' def globale: system.Global' (non l'ho provato, ma sembra impossibile) –

+0

Hum, tu Hai ragione, non esiste un modo semplice per "Foo" per esporre questi valori. Avresti bisogno almeno di un 'var' e di un cast, che è un po 'triste, vedi modifica. – gourlaysama

+1

Grazie per aver recuperato il bug ticket –

Problemi correlati