2013-04-09 6 views
12

Ho una classe in Scala, che è attualmente costruito in modo standard:Scala Constructor Deprecation

class Test(int : Int) 
{ 
    override def toString() = "Test: %d".format(int) 
} 

Tuttavia, mi piacerebbe passare al costruzione indiretta tramite un oggetto associato. Dato che la libreria che sto modificando è usata da altri, non voglio rendere subito privato il costruttore. Invece, mi piacerebbe deprecarlo e poi tornare e renderlo privato una volta che le persone hanno avuto la possibilità di cambiare il loro utilizzo. Così ho modificato il mio codice in questo modo:

object Test 
{ 
    def apply(int : Int) = new Test(int) 
} 

@deprecated("Don't construct directly - use companion constructor", "09/04/13") 
class Test(int : Int) 
{ 
    override def toString() = "Test: %d".format(int) 
} 

Tuttavia, questo depreca l'intera classe.

scala> Test(4) 
<console>:10: warning: class Test in package foo is deprecated: Don't construct directly - use companion constructor 
     val res0 = 
     ^
res0: com.foo.Test = Test: 4 

Qualcuno sa se Scala supporta la deprecazione di costruttori e, se sì, come è fatto?

risposta

10

This thread sembra descrivere la soluzione:

object Test 
{ 
    def apply(int : Int) = new Test(int) 
} 


class Test @deprecated("Don't construct directly - use companion constructor", "09/04/13") (int : Int) 
{ 
    override def toString() = "Test: %d".format(int) 
} 

non può provare in questo momento però.

+1

(modificato) Funziona, ma non è assolutamente ideale, dal momento che si riceve un avviso di deprecazione durante l'importazione di questa classe, dal momento che l'oggetto associato chiama il costruttore deprecato - qualsiasi idea su quella strada? – paulmdavies

+0

Sei sicuro? Si dovrebbe ricevere un avvertimento durante la compilazione di 'Test', ma non durante l'importazione. –

+0

Hai ragione - solo sulla compilazione. – paulmdavies

1

In termini del mio caso particolare, dove la rimozione del costruttore causa un avviso di deprecazione in fase di compilazione a causa dell'oggetto companion che utilizza il costruttore deprecato, un collega suggerisce di fornire un secondo costruttore utilizzando un parametro dummy e deprecare quello senza :

object Test 
{ 
    def apply(int : Int) = new Test(int, false) 
} 


class Test (val int : Int, dummy : Boolean) 
{ 
    @deprecated("Don't construct directly - use companion constructor", "09/04/13") 
    def this(int : Int) = this(int, false) 

    override def toString() = "Test: %d".format(int) 
} 

Questo funziona, nel senso che ci sarà solo warning di deprecazione se l'utente sta chiamando il costruttore deprecato, ma ovviamente è sgradevole - qualcuno ha una soluzione superiore?

+0

La soluzione superiore è quella già fornita da Jens Schauder –

+0

Ma non è proprio una soluzione in questo caso specifico: non è proprio l'ideale per chiedere agli utenti di sostituire qualcosa che avverte di deprecazione con qualcos'altro che avverte di deprecazione ...? – paulmdavies

+0

Ho pensato che avessi già riconosciuto che non avverte della deprecazione sul codice client (ricevi solo un avviso quando ** tu ** compili 'Test')? –