2012-04-17 55 views
6

Tengo un rasgo y una implementación que parece:El uso de @specialized en los rasgos

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 */} 
} 

me gustaría utilizar la anotación @specialized en A y B para evitar autoboxing. ¿Debo usarlo tanto en el rasgo como en la implementación, solo en la implementación o solo en el rasgo?

+0

¿Cómo esperas que funcione la especialización si estás utilizando una 'Lista' que no está especializada? No puedes evitar el boxeo entonces. –

+0

Lo siento, error al simplificar el código para publicar. La clase contiene una instancia de A (que no quiero autobox, y un 'List [Foo [A]]'. – paradigmatic

+0

Bien, pero 'Ordering' tampoco está especializado. –

Respuesta

3

El REPL tiene la respuesta correcta para nosotros, junto con javap, que mostrará el código java desensamblado. Si se agrega a la ruta de clases tools.jar REPL, usted será capaz de hacer cosas interesantes como la siguiente:

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(); 
} 

Así que ahora debería estar claro para usted que proporciona el @specialized sólo a nivel rasgo es suficiente: en la interfaz de Foo claramente tiene dos declaración de método. A mi me parece que un truco que está pasando allí, sin embargo:

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

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

Mientras que puedo responder a su pregunta, hay algunas preguntas que no puedo contestar:

  • Por qué se definen los métodos como resumen público en el rasgo?
  • ¿Por qué el método doSomething (java.lang.Object) está allí en la clase desmontada, pero no se puede invocar?
+0

Gracias, nunca logré hacer que ': javap' funcione en el REPL. – paradigmatic

+0

¿está utilizando el REPL desde la línea de comando? IDEA? Sbt? – Edmondo1984