加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

如何对Scala方法的值强制执行编译时限制?

发布时间:2020-12-16 19:22:14 所属栏目:安全 来源:网络整理
导读:我想在编译时强制限制 Scala方法的参数值. 例如: case class Foo(numberOfFoo: Int,...) numberOfFoo是一个上面的Int,但我真的想把它变成一个正整数.我已经尝试过像PositiveInt这样的类来强制执行此操作,但是这只是将检查推送到另一个仍未进行编译时检查的
我想在编译时强制限制 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")

坚持简单的事情

然而,这非常麻烦,因为无论采用哪种方法,它都将依赖于宏,并且除非在编译时已知该值,否则宏无法正常工作.如果最简单的委托方法不再有效,这可能会变得非常有限.

在实践中,绕过这种方法并使用常规方法可能更有效.无论您使用无形还是上面提到的精致库,故事都不会改变,因此对于正常的用例,运行时验证可能更简洁.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读