Scala – 合同简单设计
我正在学习
Scala作为个人项目,因为我厌倦了
Java的冗长.我喜欢我所看到的很多东西,但想知道是否有办法有效地实现一些简单的方法合同.我不是(必然)在完全DbC之后,但是有办法: –
>表示参数或类字段是必需的,即不能为空. Option事件似乎干净地表明是否存在OPTIONAL值,但我想指定类不变量(x是必需的),并且还要简洁地指定需要参数.我知道我可以做“if’s”抛出某种异常,但我想要一个非常常见的用例语言功能.我喜欢我的界面,我不喜欢防守编程. 解决方法
对于第(1)点,Option应该足够了.这是因为虽然scala支持null值,但它主要是为了与Java兼容. Scala代码不应该包含null,值,它应该被限制在非常本地化的位置,并尽快转换为选项(好的scala代码永远不会让null值传播).
因此,在惯用scala中,如果字段或参数不是Option类型,这实际上意味着它是必需的. 现在,还有(实验性的,据我所知,从未完全支持)NotNull特性.见How does the NotNull trait work in 2.8 and does anyone actually use it? 对于第(2)点,scala 2.10引入了value classes.使用它们,您可以定义自己的类,在没有运行时开销的情况下包装Int,并根据需要实现其运算符.您将进行运行时检查的唯一地方是从正常Int转换为NonNegativeInt(如果int为负,则抛出异常).请注意,每次创建新的NonNegativeInt时都会执行此检查,这也意味着每次执行操作时,都会产生非空的运行时影响.但Pascal处于相同的情况(范围检查是在运行时在Pascal中执行的)所以我猜你对此没问题. 更新:这是NonNegativeInt的示例实现(此处重命名为UInt): object UInt { def apply( i: Int ): UInt = { require( i >= 0 ) new UInt( i ) } } class UInt private ( val i: Int ) extends AnyVal { override def toString = i.toString def +( other: UInt ) = UInt( i + other.i) def -( other: UInt ) = UInt( i - other.i) def *( other: UInt ) = UInt( i * other.i) def /( other: UInt ) = UInt( i / other.i) def <( other: UInt ) = i < other.i // ... and so on } 以及REPL中的一些示例用法: scala> UInt(123) res40: UInt = 123 scala> UInt(123) * UInt(2) res41: UInt = 246 scala> UInt(5) - UInt(8) java.lang.IllegalArgumentException: requirement failed at scala.Predef$.require(Predef.scala:221) at UInt$.apply(<console>:15) ... (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |