构建和使用自定义 scala 库来扩展原始数据类型

Build and use custom scala-library to extend primitive datatypes

对于研究原型,我希望能够使用附加字段扩展原始 Scala 数据类型(例如,Double)。这不可能开箱即用,因为 scala.Doublescala.runtime.RichDouble 被声明为 final.

这是我试过的:

  1. 克隆 Scala 存储库

  2. 从文件 src/library/scala/runtime/RichDouble.scala

  3. 中的 class scala.runtime.RichDouble 中删除 final 修饰符
  4. 使用 ant 编译 Scala:ant build-opt

  5. 创建自定义 class 扩展 RichDouble:

    $ echo "class MyDouble extends scala.runtime.RichDouble {}" > MyDouble.scala

  6. 使用自定义编译的 scala 编译 MyDouble.scala

    $ build/pack/bin/scalac MyDouble.scala

但是,这会导致以下错误:

MyDouble.scala:1: error: illegal inheritance from final class RichDouble class

运行strace,自定义编译的scala-library.jar确实正在加载:

$ strace -f ./build/pack/bin/scalac MyDouble.scala 2>&1 | grep scala-library
stat("/my/custom/dir/scala/build/pack/lib/scala-library.jar", {st_mode=S_IFREG|0664, st_size=5682113, ...}) = 0

我错过了什么?为什么即使我删除了修饰符,class RichDouble 仍然报告为 final

你可以看看implicit classes:它们是为了扩展封闭类而设计的。

implicit class MyDouble(d: Double) {
  def myNewFeature() = println("MyDouble is $d")
}
val d1 = new Double(42) // just instantiate a Double
d1.myNewFeature() // scala will do implicit conversion

我试图做的是不可能的。 Double 等原始类型被实现为 value classes, which are implicitly final. As such, it is one of their essential limitations ,它们无法扩展。