2012-04-17 33 views
6

Ho un tratto e un'implementazione che sembra:L'utilizzo di @specialized a tratti

trait Foo[A] { 
    def bar[B >: A: Ordering]: Foo[B] 
} 
class FooImpl[A](val a: A, val values: List[Foo[A]]) extends Foo[A] { 
    def bar[B >: A] = { /* concrete implementation */} 
} 

Vorrei utilizzare il @specialized annotazione A e B per evitare autoboxing. Devo usarlo sia in tratto che in implementazione, solo in implementazione o solo in tratto?

+0

Come ti aspetti che la specializzazione funzioni se stai utilizzando un 'Elenco' che non è specializzato in se stesso? Non si può quindi evitare la boxe. –

+0

Siamo spiacenti, errore nel semplificare il codice per la pubblicazione. La classe contiene un'istanza di A (che non desidero autobox e un 'List [Foo [A]]'. – paradigmatic

+0

Ok, ma 'Ordering' non è specializzato –

risposta

3

Il REPL ha la risposta giusta per noi, insieme a javap, che mostrerà il codice java disassemblato. Se si aggiunge tools.jar al classpath REPL, si sarà in grado di fare cose interessanti come la seguente:

scala> trait Foo[@specialized(Int) A] { def doSomething(a:A)} 
defined trait Foo 

scala> :javap -p Foo 
Compiled from "<console>" 
public interface Foo{ 
    public abstract void doSomething(java.lang.Object); 
    public abstract void doSomething$mcI$sp(int); 
} 

scala> class Hello extends Foo[Int] { def doSomething(a:Int)=println(a)} 
defined class Hello 

scala> :javap -p Hello 
Compiled from "<console>" 
public class Hello extends java.lang.Object implements Foo$mcI$sp,scala.ScalaObject{ 
    public void doSomething(int); 
    public void doSomething$mcI$sp(int); 
    public void doSomething(java.lang.Object); 
    public Hello(); 
} 

Così ora dovrebbe essere chiaro a voi che fornire il @specialized solo a livello caratteristica è sufficiente: nell'interfaccia Foo hai chiaramente due dichiarazioni di metodo. Sembra a me che un trucco sta succedendo lì, però:

scala> new Hello 
res0: Hello = [email protected] 

scala> res0.doSomething("test") 
<console>:11: error: type mismatch; 
found : java.lang.String("test") 
required: Int 

Mentre posso rispondere alla tua domanda, ci sono alcune domande che non posso rispondere:

  • Perché i metodi sono definiti come astratto pubblico nel tratto?
  • Perché il metodo doSomething (java.lang.Object) è presente nella classe disassemblata, ma non può essere chiamato?
+0

Grazie, non sono mai riuscito a eseguire ': javap' nel REPL. – paradigmatic

+0

stai usando REPL dalla riga di comando? IDEA? Sbt? – Edmondo1984