有时使用import语句来访问对象的多个元素是方便和清晰的.
例如,代码
x.y.z.a = 1
x.y.z.b = 2
x.y.z.c = 3
Run Code Online (Sandbox Code Playgroud)
可写成
{
import x.y.z._
a = 1
b = 2
c = 3
}
Run Code Online (Sandbox Code Playgroud)
显然,当名字更长时,它会更有用.
所有工作都是在编译时完成的,还是以某种方式在运行时执行import语句?使用这种风格是否有任何成本,效率或其他方面的成本?
是的,所有名称和隐式都在编译时解析,并且import不会影响其他任何内容。
当然,执行的仍然是
x.y.z.a = 1
x.y.z.b = 2
x.y.z.c = 3
Run Code Online (Sandbox Code Playgroud)
所以你会获取x.y.z3 次(在本例中)。如果z是
package x.y
object z { ... }
Run Code Online (Sandbox Code Playgroud)
这又只是名称解析;但如果你有类似的东西
object x {
val y = ... // some type which has val z
}
Run Code Online (Sandbox Code Playgroud)
每次调用 2 个方法,并将其放入z局部变量中效果更好(但如果此代码运行得足够频繁,JIT 可能会对此进行优化)。
你可以自己检查一下javap.从这样的事情开始:
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"
}
}
Run Code Online (Sandbox Code Playgroud)
编译scalac Test.scala然后javap -c Test\$:
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
...
Run Code Online (Sandbox Code Playgroud)
字面上相同的字节码.