scala - 我应该如何在 Scala 中创建 Int 的子类型?
问题描述
如何创建多个本质上是 Ints 的类型,即可以获得 int 值,可以使用 + BUT 等数学运算符,其中不同类型的实例不能混合。
例如:
val density1 = new Density(100)
val density2 = new Density(200)
density1 + density2 should be(new Density(300))
val variability = new Variability(1)
variability.value should be(1)
density1 + variability // does not compile
可能有数百种这样的类型,我不想在每个叶类中实现像 + 这样的运算符。
理想情况下,我想避免所有隐式转换机制(仅限个人喜好)。其他类型不应要求更改现有类型。
解决方案
这是 Scala 3 中的一个解决方案,我认为它不使用装箱/拆箱:
object Wrappers:
opaque type Wrapper = Int
extension[T <: Wrapper](t: T)(using util.NotGiven[T =:= Wrapper]):
def +(other: T): T = (t + other).asInstanceOf[T]
//other methods
opaque type Density <: Wrapper = Int
def Density(i: Int): Density = i
opaque type Variability <: Wrapper = Int
def Variability(i: Int): Variability = i
测试:
val density1 = Density(1)
val density2 = Density(2)
val density3: Density = density1 + density2 //compiles
val check1: Variability = density1 + density2 //doesn't compile
val variability = Variability(1)
val check2 = (variability: Wrapper) + density2 //doesn't compile
val check3 = variability + density2 //doesn't compile
println(density1) //1
println(density2) //2
println(density3) //3
未asInstanceOf
选中,不应影响性能。这种设计也应该Int
避免 s 被装箱,但我不能保证,这也取决于你如何使用它。另一个好处是每个新类型只需要多两行代码。为了使添加新方法更容易,您可能还可以创建自己的新方法来缩短asInstanceOf[T]
.
推荐阅读
- google-cloud-platform - 如何限制对通过谷歌云运行部署的 URL 的访问?
- javascript - 使用 Jest-expo 测试异步存储的示例用例?
- reactjs - 是否可以通过状态参数传递函数
- c++ - 不能在 C++ 类中重载 + 运算符
- python - 如何在python递归中获取return语句
- c# - 删除基于重复元素值的 XML 记录集
- node.js - AWS Kinesis Firehose 未响应 Lambda
- javascript - 尽管计时器已停止/暂停,但 Javascript 秒表会在页面重新加载/刷新时忽略停止时间
- javascript - 获取不依赖于客户端浏览器的语言环境时间
- java - 如何处理“不再支持 resteasy.scan。使用 servlet 3.0 容器和 ResteasyServletInitializer”错误