使用

2012-04-17 14 views
6

我有一个特质和看起来像一个实现:使用

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注释上AB避免自动装箱。我是否需要在特质和实施中使用它,仅在实施中使用,还是只在特性中使用?

+0

如果你正在使用一个本身不专用的'List',你如何期待专业化?那么你无法避免拳击。 – 2012-04-17 16:01:40

+0

对不起,错误简化发布代码。这个类包含一个A的实例(我不想自动装箱,还有一个'List [Foo [A]]' – paradigmatic 2012-04-17 16:06:40

+0

好吧,但'Ordering'也不是专门的。 – 2012-04-17 16:14:38

回答

3

REPL为我们提供了正确的答案,还有javap,它将显示反汇编后的java代码。如果添加的tools.jar到您的REPL的classpath,你就可以做很酷的事情如下所示:

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 2012-06-27 10:09:59

+0

您是否使用命令行中的REPL? IDEA?sbt? – Edmondo1984 2012-06-27 11:40:16