2012-04-17 3 views
6

У меня есть черта и реализация перспективной как:Использования @specialized в черт

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

Я хотел бы использовать @specialized аннотации A и B избежать Autoboxing. Нужно ли использовать его как в свойствах, так и в реализации, только в реализации или только в чертах?

+0

Как вы ожидаете, что специализация будет работать, если вы используете «Список», который не является специализированным? Тогда вы не можете избежать бокса. –

+0

Извините, ошибка в упрощении кода для публикации. Класс содержит экземпляр A (который я не хочу использовать autobox и 'List [Foo [A]]'. – paradigmatic

+0

Хорошо, но 'Ordering' также не является специализированным. –

ответ

3

REPL имеет правильный ответ для нас вместе с javap, который покажет дизассемблированный код Java. Если добавить tools.jar к вашему REPL классам, вы сможете делать классные вещи, как следующее:

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

Так что теперь должно быть ясно, что предоставление @specialized только на уровне признака достаточно: в интерфейсе Foo у вас явно есть два объявления метода. Она смотрит на меня, что трюк там происходит, однако:

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

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

В то время как я могу ответить на ваш вопрос, есть некоторые вопросы, которые я не могу ответить:

  • Почему методы определены как публичный аннотация в признаке?
  • Почему метод doSomething (java.lang.Object) существует в дизассемблированном классе, но не может быть вызван?
+0

Спасибо, мне никогда не удалось сделать работу ': javap' в REPL. – paradigmatic

+0

вы используете REPL из командной строки? IDEA? Sbt? – Edmondo1984

Смежные вопросы