在Scala中使用构造函数
|
我一直在
Scala做一些练习.我想我可能会尝试使用新添加的AnyVal特性来创建一种创建不兼容的值类型的方法,这些值不能被意外地相互分配.
我能想到的最好的是这样的: object Measurements {
trait ValueType[T] extends Any {
def value: T
}
trait Measurement[A <: ValueType[Double]] extends Any {
def modify(fn: (Double,A) => Double,value: A): A
def +(mod: A) = modify((x: Double,y: A) => x + y.value,mod)
def -(mod: A) = modify((x: Double,y: A) => x - y.value,mod)
def *(mod: A) = modify((x: Double,y: A) => x * y.value,mod)
def /(mod: A) = modify((x: Double,y: A) => x / y.value,mod)
}
case class Frequency(value: Double) extends AnyVal
with ValueType[Double]
with Measurement[Frequency]
{
def modify(fn: (Double,Frequency) => Double,mod: Frequency)
= Frequency(fn(value,mod))
}
case class Amplitude(value: Double) extends AnyVal
with ValueType[Double]
with Measurement[Amplitude]
{
def modify(fn: (Double,Amplitude) => Double,mod: Amplitude)
= Amplitude(fn(value,mod))
}
case class Wavelength(value: Double) extends AnyVal
with ValueType[Double]
with Measurement[Wavelength]
{
def modify(fn: (Double,Wavelength) => Double,mod: Wavelength)
= Wavelength(fn(value,mod))
}
}
import Measurements._
Frequency(150) + Frequency(10) // ==> Frequency(160)
Amplitude(23.2) * Amplitude(2) // ==> Amplitude(46.4)
Amplitude(50) + Frequency(50) // ==> Compile-time Type Error
不幸的是,它要求我为每个实例唯一地定义修改函数,因为不可能用通用类型A定义类似A(值)的东西.似乎没有办法定义构造函数约束.否则我可以在特征上定义一些常见的东西,例如: def modify(fn: (Double,mod: A) = A(fn(value,mod)) 我试过在A上调用apply(Double),但是无法从泛型变量访问它.我还试着看看我是否能够建立一个至少可以简化工作的工厂,但却无法提出比我现在做的更优雅的东西.我一直遇到与C#相同的问题. 是否有某种方法可以分解出依赖于不同(但相关)类的通用构造函数类型的代码? 解决方法
我不认为这是可能的,如果不诉诸运行时反射(或可能是宏).基本上有三个问题,你已经指出了两个问题:
>特征不可能声明强制构造函数签名. 我能想到的最好的方法是以下方法.注意,它使用反射,如果Measurement的具体实例没有声明适当的构造函数,则可以在运行时抛出异常. // ... as above ...
trait Measurement[A <: ValueType[Double]] extends Any { self: A =>
def modify(fn: (Double,mod: A): A =
this.getClass
.getConstructor(this.getClass)
.newInstance(fn(value,mod): java.lang.Double)
// ... as above ...
}
case class Frequency(value: Double)
extends AnyVal
with ValueType[Double]
with Measurement[Frequency]
// ... etc ...
Frequency(150) + Frequency(10) // ==> Frequency(160)
Amplitude(23.2) * Amplitude(2) // ==> Amplitude(46.4)
Amplitude(50) + Frequency(50) // ==> Compile-time Type Error
自我类型注释self:A确保ValueType声明的值字段可从内部特征Measurement中访问. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
