如何对Scala方法的值强制执行编译时限制?
我想在编译时强制限制
Scala方法的参数值.
例如: case class Foo(numberOfFoo: Int,...) numberOfFoo是一个上面的Int,但我真的想把它变成一个正整数.我已经尝试过像PositiveInt这样的类来强制执行此操作,但是这只是将检查推送到另一个仍未进行编译时检查的类. 使用上面的例子,我想要这个: val n: Int = ... val f: Foo = Foo(n) 如果n>编译0并且如果n< = 0则不编译.我不希望实例化代码必须处理可能的异常,处理Option [Foo],或者最终得到Foo,其中Foo.numberOfFoo!= n(即我不想使用输入参数的绝对值). 更新:感谢您提供有用的信息.就像我担心的那样.大多数情况下,我希望能够指定必须具有正整数大小的东西的大小.所以这似乎是最好的方法: case class Foo(bar: Bar) {val n = bar size} 解决方法
另一种方法是使用无形库,并使用Nat.限制是您需要在编译时基本上使用已知常量实例化那些Foo实体.
import shapeless.ops.nat_ import shapeless.nat._ case class Foo[T <: Nat](numberOfFoo: Int)(implicit ev: GT[T,_0] object Foo { // The problem is this won't work. def apply[T <: Nat](n: Int): Foo[T] = Foo(Nat(n)) } 只有在这样使用时才会起作用: Foo(_1) _1来自shapeless.nat._.如果深入研究实现,即使没有你的意思,0部分也会被强制执行: if (n < 0) c.abort(c.enclosingPosition,s"A Nat cannot represent $n") 坚持简单的事情 然而,这非常麻烦,因为无论采用哪种方法,它都将依赖于宏,并且除非在编译时已知该值,否则宏无法正常工作.如果最简单的委托方法不再有效,这可能会变得非常有限. 在实践中,绕过这种方法并使用常规方法可能更有效.无论您使用无形还是上面提到的精致库,故事都不会改变,因此对于正常的用例,运行时验证可能更简洁. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |