对于研究原型,我希望能够使用其他字段扩展原始Scala数据类型(例如,Double
)。由于scala.Double
和scala.runtime.RichDouble
被声明为final
,因此无法开箱即用。
这是我尝试过的:
克隆scala存储库
从文件final
scala.runtime.RichDouble
移除src/library/scala/runtime/RichDouble.scala
修饰符
使用ant编译Scala:ant build-opt
创建一个扩展RichDouble
的自定义类:
$ echo "class MyDouble extends scala.runtime.RichDouble {}" > MyDouble.scala
使用自定义编译的scala编译MyDouble.scala
:
$ build/pack/bin/scalac MyDouble.scala
然而,这会导致以下错误:
MyDouble.scala:1:错误:来自最终类RichDouble类的非法继承
使用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
我错过了什么?即使我删除了修饰符,为什么类RichDouble
仍然报告为final
?
答案 0 :(得分:1)
您可以查看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
答案 1 :(得分:1)
我想做的事情是不可能的。原始类型(例如Double
)实现为value classes,隐式final
。因此,他们essential limitations中的一个是他们无法扩展的。