0

与えられた:

$cat build.sbt
scalaVersion := "2.12.1"

$cat src/main/scala/net/X.scala
package net 

trait Foo 
object X {

    val a: Int with Foo = 42.asInstanceOf[Int with Foo]

    println(a + a)

}

経由でコンパイルした後、出力ファイルsbt compilejavapしました。class

$javap target/scala-2.12/classes/net/X\$.class 
Compiled from "X.scala"
public final class net.X$ {
  public static net.X$ MODULE$;
  public static {};
  public int a();
}

$javap target/scala-2.12/classes/net/X.class 
Compiled from "X.scala"
public final class net.X {
  public static int a();
}

なぜa型があるのintですか?

Int with Fooinのタイプを指定していましたobject X

4

1 に答える 1

2

これは、Scala のすべての交差タイプが JVM バイトコードにコンパイルされる方法です。JVM には のようなものを表す方法がないInt with Fooため、コンパイラは型を最初の「単純な」型に消去しIntます。この場合。aこれは、値を a のように使用する場合Foo、コンパイラはキャストをバイトコードに挿入する必要があることを意味します。

次の REPL セッションを見てください。

Welcome to Scala 2.12.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_111).
Type in expressions for evaluation. Or try :help.

scala> trait Foo { def foo = "foo" }
defined trait Foo

scala> trait Bar { def bar = "bar" }
defined trait Bar

scala> class FooBar extends Foo with Bar
defined class FooBar

scala> class Test { val foobar: Foo with Bar = new FooBar }
defined class Test

scala> object Main {
     |   def main(): Unit = {
     |     val test = new Test().foobar
     |     println(test.foo)
     |     println(test.bar)
     |   }
     | }
defined object Main

scala> :javap -p -filter Test
Compiled from "<console>"
public class Test {
  private final Foo foobar;
  public Foo foobar();
  public Test();
}

scala> :javap -c -p -filter Main
Compiled from "<console>"
  ...
  public void main();
    Code:
      ...
      15: invokeinterface #62,  1           // InterfaceMethod Foo.foo:()Ljava/lang/String;
      ...
      27: checkcast     #23                 // class Bar
      30: invokeinterface #69,  1           // InterfaceMethod Bar.bar:()Ljava/lang/String;
      ...

Int with Foo実際には特殊なケースです。Intは最終型でFooあり、特性です。どうやらコンパイラは、特性よりも最終的な型とクラスを好むようです。そのため、Foo with BarwhereFooは trait であり、Baris はクラスであっても、型は のBar代わりに消去されFooます。

于 2017-01-07T19:18:37.490 に答える