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注釈Aを使用してB、自動ボクシングを回避したいと思います。トレイトと実装の両方で使用する必要がありますか、実装のみで使用する必要がありますか、それともトレイトでのみ使用する必要がありますか?

4

1 に答える 1

3

REPLは、分解されたJavaコードを表示するjavapとともに、正しい答えを持っています。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インターフェースでは、明らかに2つのメソッド宣言があります。しかし、そこではトリックが行われているように見えます。

scala>  new Hello
res0: Hello = Hello@7a80747

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

私はあなたの質問に答えることができますが、私が答えることができないいくつかの質問があります:

  • メソッドがトレイトでパブリックアブストラクトとして定義されているのはなぜですか?
  • メソッドdoSomething(java.lang.Object)が逆アセンブルされたクラスにあるのに、呼び出すことができないのはなぜですか?
于 2012-06-27T09:12:54.637 に答える