【发布时间】:2014-11-13 09:52:06
【问题描述】:
我想使用案例类来更有表现力地描述我的数据类型,以便从更高的静态正确性中受益。目标是 100% 静态确定存在的任何 Age 值始终包含有效的人类年龄(撇开封装规则可以使用反射绕过这一事实不谈)。
例如,我没有使用Int 来存储人的年龄,而是:
case class Age(x: Int) extends AnyVal
def mkAge(x: Int) = if (0 <= x && x <= 150) Some(Age(x)) else None
def unwrapAge(age: Age) = age.x
但是,此实现存在以下事实:Age 仍然可以在不经过 mkAge 和 unwrapAge 的情况下被实例化。
接下来,我尝试将构造函数设为私有:
case class Age private(x: Int) extends AnyVal
object Age {
def make(x: Int) = if (0 <= x && x <= 150) Some(Age(x)) else None
def unwrap(age: Age) = age.x
}
然而,虽然这确实阻止了 Age 使用 new 实例化(例如 new Age(3)),但 object Age 中自动生成的 apply(x: Int) 仍然很容易访问。
那么,问题来了:除了Age.make 或mkAge 之外,如何隐藏伴随对象中的构造函数和默认apply 方法?
我想避免必须使用常规(非case)类并手动正确复制class Age 和object Age 中的自动生成方法。
【问题讨论】:
标签: scala static-typing