我知道@specialized
类和值类是如何工作的,并且我知道我不能有一个专门的值类,例如:
class MilliVolt[@specialized T](val content :T) extends AnyVal //illegal
我找不到获得类似效果的方法:使用单个声明创建一个用户类型/类型构造函数,它可以作为几个 java 原语的纯句法包装器 - 是否可以解决这个限制?
值类背后的主要动机之一是用业务意义“注释”值类型并创建与其数据类型不同的类型:
class MilliVolts(val count :Long) extends AnyVal
只要您静态地知道盒装类型,这就会非常有效,但是如果您想将几个不同的基元视为毫伏,您可以选择为每个基元创建一个新的包装器,或者对它们的设计使用泛型至:
trait Scale
trait millivolts extends Scale
trait milliampere extends Scale
class of[N, U<:Scale](val amount :N) extends AnyVal
val voltage :Long of millivolts = new of(1L)
val current :Int of milliampere = new of(1)
这一切都很甜蜜,并且确实of
在编译时删除了包装器,但不幸的是,原语被装箱到它们的 java 包装器中,并且这两个字段被编译为:
Integer voltage = scala.Long.box(1L)
Integer current = scala.Int.box(1)
而不是long
和int
领域。
是否可以编写以下代码:
- 允许使用单个声明创建新的此类包装器(新的“单元”类型);
- 至少在底层原语方面对此类包装器执行通用操作(以毫伏为单位的方法,从盒装原语中抽象出来);
- 当包装器类型和底层原始类型都被完全实例化(不是泛型类型的类型参数)并且可以内联调用的方法时不执行装箱(所以我可以为所有当前和未来的单元定义一次添加)
- 理想情况下不依赖于客户端代码中的宏(实现中的使用很好,只要类型声明本身可以被 IDE 理解)