【发布时间】:2015-04-15 15:55:59
【问题描述】:
这是一个简单的问题。
为什么与Int相关的方法不在Int中?
相反,Scala 会费心将相关方法放入RichInt 并依赖隐式转换,以便让它们像Int 的方法一样工作。
何必呢?
【问题讨论】:
这是一个简单的问题。
为什么与Int相关的方法不在Int中?
相反,Scala 会费心将相关方法放入RichInt 并依赖隐式转换,以便让它们像Int 的方法一样工作。
何必呢?
【问题讨论】:
Scala 并不存在于真空中。它专门被设计为托管在一个生态系统中/一个主要为另一种语言设计的平台上:Java 平台、.NET 平台、ECMAScript 平台、Cocoa 等。
这意味着在某些情况下必须做出妥协,以使 Scala 与宿主平台的生态系统、库和语言无缝、高效且高性能地运行。这就是为什么它有 null,为什么它有类(它可以只使用特征,并允许特征有构造函数),为什么它有包(因为它们可以干净地映射到 Java 包或 .NET 命名空间),为什么它没有适当的尾调用,没有具体化的泛型等。这就是为什么它有花括号的原因,不是为了更容易与 Java 集成,而是为了更容易与 Java 开发人员的大脑集成。
scala.Int是一个假类,它代表一个原生平台整数(Java中的原始int,.NET中的System.Int32等)是假的,它除了操作之外真的没有任何方法由宿主环境提供。
替代方法是将所有操作都放在Int 类中,并让编译器知道哪些方法是本机的,哪些不是。但这是一种特殊情况,在general 中集中精力使“enrich-my-library”更快更有意义,这样所有程序员都可以从这些优化中受益花费时间、金钱和资源进行仅适用于十二个左右的类的优化。
【讨论】:
问题是为什么不对Int 进行丰富的建模,然后对其进行优化,例如,它具有未装箱的表示,并且某些操作是本机提供的?
答案肯定是编译器还不是很擅长这些优化。
scala> 42.isWhole
res1: Boolean = true
scala> :javap -prv -
[snip]
9: getstatic #26 // Field scala/runtime/RichInt$.MODULE$:Lscala/runtime/RichInt$;
12: getstatic #31 // Field scala/Predef$.MODULE$:Lscala/Predef$;
15: bipush 42
17: invokevirtual #35 // Method scala/Predef$.intWrapper:(I)I
20: invokevirtual #39 // Method scala/runtime/RichInt$.isWhole$extension:(I)Z
23: putfield #17 // Field res1:Z
26: return
或欠优化
9: getstatic #26 // Field scala/runtime/RichInt$.MODULE$:Lscala/runtime/RichInt$;
12: getstatic #31 // Field scala/Predef$.MODULE$:Lscala/Predef$;
15: astore_1
16: bipush 42
18: invokevirtual #35 // Method scala/runtime/RichInt$.isWhole$extension:(I)Z
21: putfield #17 // Field res0:Z
24: return
【讨论】: