我理解这些方法可能被认为是"等同的"或"同义词",尽管不是"相同的",根据诸如调用collection.size或collection.length和Scala Buffer 的最佳Scala约定之类的问题:大小或长度?.
但这是否意味着他们是一样的?
不要向我提供相同的意见或虚假的概念.告诉我他们什么时候不一样.
用坚硬的科学来支持你的主张!
字节代码就足够了.我对JIT特定的优化并不那么感兴趣.
我对世界目前的状况特别感兴趣,即最近的里程碑中的Scala 2.11.
字符串和数组仍然包装在2.11中.
你应该训练你的手指打字s.length和arr.length.
这并不难,因为字符串和数组都有长度.
从Java进入Scala的人经常会决定是使用方法java.lang.String还是方便的扩充.由于在我们需要用休息室的甜甜圈补充它之前我们有一个有限的"决策预算" ,因此作为一个政策问题,值得做出一些这些决定.
万一没有什么比午餐或甜甜圈更好的讨论了:
22: invokevirtual #41 // Method scala/Predef$.augmentString:(Ljava/lang/String;)Ljava/lang/String;
25: invokespecial #44 // Method scala/collection/immutable/StringOps."<init>":(Ljava/lang/String;)V
28: invokevirtual #47 // Method scala/collection/immutable/StringOps.size:()I
18: invokevirtual #39 // Method scala/Predef$.intArrayOps:([I)Lscala/collection/mutable/ArrayOps;
21: invokeinterface #44, 1 // InterfaceMethod scala/collection/mutable/ArrayOps.size:()I
Run Code Online (Sandbox Code Playgroud)
等等,等待,你可以失去augmentString.
它GenSeqLike引入length并指定它"产生与...相同的结果" size. SeqLike以这种方式实现它.
实际上,通过增强来String获取一种size方法SeqLike,具体而言StringLike.这需要包装.实际上,要预测哪些调用需要换行或调度到扩展方法并不容易.
例如,length以不需要包装的方式定义.那是因为StringOps是一个价值类.事实上,它编译成String.length.
但是,apply方法on StringOps,定义为charAt模拟数组的调用,虽然以相同的方式定义,但调用扩展方法.
(当然,在JIT编译之后,一些操作码和分配可能没什么意义.)
scala> val s = "hello"
s: String = hello
scala> val n = s.length ; val i = s.size ; val c = s(4) ; s.slice(0,4)
n: Int = 5
i: Int = 5
c: Char = o
res0: String = hell
scala> :javap -prv -
public $line4.$read$$iw$$iw$();
flags: ACC_PUBLIC
Code:
stack=5, locals=7, args_size=1
0: aload_0
1: invokespecial #32 // Method java/lang/Object."<init>":()V
4: aload_0
5: putstatic #34 // Field MODULE$:L$line4/$read$$iw$$iw$;
8: aload_0
9: getstatic #39 // Field $line3/$read$$iw$$iw$.MODULE$:L$line3/$read$$iw$$iw$;
12: invokevirtual #42 // Method $line3/$read$$iw$$iw$.s:()Ljava/lang/String;
Run Code Online (Sandbox Code Playgroud)
length:
15: invokevirtual #47 // Method java/lang/String.length:()I
18: putfield #22 // Field n:I
21: aload_0
Run Code Online (Sandbox Code Playgroud)
new StringOps,或StringOops:
22: new #49 // class scala/collection/immutable/StringOps
25: dup
26: getstatic #54 // Field scala/Predef$.MODULE$:Lscala/Predef$;
29: getstatic #39 // Field $line3/$read$$iw$$iw$.MODULE$:L$line3/$read$$iw$$iw$;
32: invokevirtual #42 // Method $line3/$read$$iw$$iw$.s:()Ljava/lang/String;
35: astore_2
36: astore_1
37: aload_2
Run Code Online (Sandbox Code Playgroud)
StringOps.size:
38: invokespecial #57 // Method scala/collection/immutable/StringOps."<init>":(Ljava/lang/String;)V
41: invokevirtual #60 // Method scala/collection/immutable/StringOps.size:()I
44: putfield #25 // Field i:I
47: aload_0
48: getstatic #65 // Field scala/collection/immutable/StringOps$.MODULE$:Lscala/collection/immutable/StringOps$;
51: getstatic #54 // Field scala/Predef$.MODULE$:Lscala/Predef$;
54: getstatic #39 // Field $line3/$read$$iw$$iw$.MODULE$:L$line3/$read$$iw$$iw$;
57: invokevirtual #42 // Method $line3/$read$$iw$$iw$.s:()Ljava/lang/String;
60: astore 4
62: astore_3
63: aload 4
65: iconst_4
Run Code Online (Sandbox Code Playgroud)
apply 扩展方法:
66: invokevirtual #69 // Method scala/collection/immutable/StringOps$.apply$extension:(Ljava/lang/String;I)C
69: putfield #28 // Field c:C
72: aload_0
73: getstatic #65 // Field scala/collection/immutable/StringOps$.MODULE$:Lscala/collection/immutable/StringOps$;
76: getstatic #54 // Field scala/Predef$.MODULE$:Lscala/Predef$;
79: getstatic #39 // Field $line3/$read$$iw$$iw$.MODULE$:L$line3/$read$$iw$$iw$;
82: invokevirtual #42 // Method $line3/$read$$iw$$iw$.s:()Ljava/lang/String;
85: astore 6
87: astore 5
89: aload 6
91: iconst_0
92: iconst_4
Run Code Online (Sandbox Code Playgroud)
并且slice:
93: invokevirtual #73 // Method scala/collection/immutable/StringOps$.slice$extension:(Ljava/lang/String;II)Ljava/lang/String;
96: putfield #31 // Field res0:Ljava/lang/String;
99: return
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1938 次 |
| 最近记录: |