有時,使用import
語句來訪問對象的多個元素會更方便和更清晰。在scala中代碼塊導入昂貴
例如,代碼
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
語句來訪問對象的多個元素會更方便和更清晰。在scala中代碼塊導入昂貴
例如,代碼
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
不影響其他任何東西。
當然,什麼得到執行的仍然是
x.y.z.a = 1
x.y.z.b = 2
x.y.z.c = 3
所以你獲取(在這個例子中)x.y.z
3倍。如果z
是
package x.y
object z { ... }
這再次只是名稱解析;但相反,如果你碰到這樣的
object x {
val y = ... // some type which has val z
}
這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"
}
}
編譯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
...
字面上相同的字節碼。