2016-11-10 5 views
2

importステートメントを使用してオブジェクトの複数の要素にアクセスすると便利な場合があります。コードブロックのインポート内でスケーラビリティが高い

例えば、コード

x.y.z.a = 1 
x.y.z.b = 2 
x.y.z.c = 3 

は名前が長いとき、明らかに、それははるかに便利です

{ 
    import x.y.z._ 

    a = 1 
    b = 2 
    c = 3 
} 

のように記述することができます。

すべての作業はコンパイル時に実行されるのですか、実行時に何らかの形で実行されるimport文ですか?このスタイルを使用するのに効率性などの面でコストがかかりますか?

答えて

4

はい、すべての名前と内容はコンパイル時に解決され、importは他に影響しません。もちろん

は、どのような実行されますと、あなたは(この例では)x.y.z 3回をフェッチしますまだ

x.y.z.a = 1 
x.y.z.b = 2 
x.y.z.c = 3 

です。 z

package x.y 
object z { ... } 

である場合、これはもう一度だけ名前解決です。代わり場合は

object x { 
    val y = ... // some type which has val z 
} 

のようなものを持っている、それは2の方法だたびに呼び出し、ローカル変数にzを置くことは、より良い実行する(しかし、このコードは十分な頻度で実行されている場合JITはこれを最適化することができます)。

5

javapでご自分で確認できます。

public void withImport(); 
    descriptor:()V 
    flags: ACC_PUBLIC 
    Code: 
     stack=2, locals=1, args_size=1 
     0: getstatic  #18     // Field x/y/z$.MODULE$:Lx/y/z$; 
     3: ldc   #20     // String zyx 
     5: invokevirtual #24     // Method x/y/z$.a_$eq:(Ljava/lang/String;)V 
     8: getstatic  #18     // Field x/y/z$.MODULE$:Lx/y/z$; 
     11: ldc   #26     // String wvu 
     13: invokevirtual #29     // Method x/y/z$.b_$eq:(Ljava/lang/String;)V 
     16: getstatic  #18     // Field x/y/z$.MODULE$:Lx/y/z$; 
     19: ldc   #31     // String rst 
     21: invokevirtual #34     // Method x/y/z$.c_$eq:(Ljava/lang/String;)V 
     24: return 
     LocalVariableTable: 
     Start Length Slot Name Signature 
      0  25  0 this LTest$; 
     LineNumberTable: 
     line 13: 0 
     line 14: 8 
     line 15: 16 

    public void withoutImport(); 
    descriptor:()V 
    flags: ACC_PUBLIC 
    Code: 
     stack=2, locals=1, args_size=1 
     0: getstatic  #18     // Field x/y/z$.MODULE$:Lx/y/z$; 
     3: ldc   #20     // String zyx 
     5: invokevirtual #24     // Method x/y/z$.a_$eq:(Ljava/lang/String;)V 
     8: getstatic  #18     // Field x/y/z$.MODULE$:Lx/y/z$; 
     11: ldc   #26     // String wvu 
     13: invokevirtual #29     // Method x/y/z$.b_$eq:(Ljava/lang/String;)V 
     16: getstatic  #18     // Field x/y/z$.MODULE$:Lx/y/z$; 
     19: ldc   #31     // String rst 
     21: invokevirtual #34     // Method x/y/z$.c_$eq:(Ljava/lang/String;)V 
     24: return 
     ... 

文字通り同じバイトコード:scalac Test.scala、その後javap -c Test\$

package x.y { 
    object z { 
    var a = "abc" 
    var b = "def" 
    var c = "ghi" 
    } 
} 

object Test { 
    def withImport: Unit = { 
    import x.y.z._ 

    a = "zyx" 
    b = "wvu" 
    c = "rst" 
    } 

    def withoutImport: Unit = { 
    x.y.z.a = "zyx" 
    x.y.z.b = "wvu" 
    x.y.z.c = "rst" 
    } 
} 

コンパイル:このような何かを起動します。

関連する問題