在斯卡拉功能的断言(Functional assertion in Scala)

2019-08-22 07:35发布

是否有内置的断言支持返回结果?

这是非常非功能来做到这一点:

  def addPositive(a: Int, b: Int) = {
    assert(a > 0 && b > 0)
    a + b
  }

我宁愿做类似的东西:

  def addPositive(a: Int, b: Int) = 
    assert(a > 0 && b > 0)(a + b)

这样一来,我可以断言回避的必要环节。 (后者不编译)任何类似可用?

Answer 1:

函数式编程把功能作为纯粹的数学函数(理想)。 那么什么是数学的说法一个功能不适用于某些参数的工作,必须炸毁的方式吗?

部分功能

事实证明,Scala有这个概念相当不错的支持: PartialFunction 。 这是你将如何使用部分功能重写代码:

val addPositive: PartialFunction[(Int, Int), Int] = {
  case (a, b) if a > 0 && b > 0 => a + b
}

这样做有几个好处:

如果你用错误的参数调用它,它会抛出一个MatchError例外。

addPositive(-1, 2) => Exception in thread "main" scala.MatchError: (-1,2) (of class scala.Tuple2$mcII$sp)

实际上,你可以品尝功能的域来检查某些值是非常适合作为函数的参数:

addPositive.isDefinedAt(-1, 2) => false

如果你想给函数适用于一些参数,并得到两种结果,或者一些值,指示故障,则可以lift它返回Option

addPositive.lift(-1, 2) => None
addPositive.lift(1, 2) => Some(12)

您可以与其他功能,在参数无效的情况下提供备用撰写它:

val fallback: PartialFunction[(Int, Int), Int] = { case (a, b) => Int.MinValue }
val f = addPositive orElse fallback

f(-1, 2) => -2147483648

或处理一个自定义的方式错误:

val raiseError: PartialFunction[(Int, Int), Int] = {
  case (a, b) => throw new IllegalArgumentException(s"Cannot apply addPositive to arguments $a and $b")
}
val g = addPositive orElse raiseError

g(-1, 2) => Exception in thread "main" java.lang.IllegalArgumentException: Cannot apply addPositive to arguments -1 and 2

它与标准库运作良好:看Seq.collectSeq.collectFirst

此外PartialFunction是一种正常的一元函数,所以你继承所有功能操作为好。

下面是在一篇文章中解释斯卡拉非常典雅的部分功能:

阶部分功能(没有博士)



Answer 2:

你可以推出自己的实现:

def assert[T](cond: =>Boolean)(expr: =>T): T = {
  assert(cond)
  expr
}

你也可以使用的选项类型,以避免例外,但是这意味着你以后要对结果模式匹配:

def addPositive(a: Int, b: Int): Option[int] =
  if (a > 0 && b > 0) Some(a + b)
  else None

这可以以类似的方式为被重构assert上述变体。



Answer 3:

还有就是require为前提,这几乎完成你想要的功能。 你可以做

def addPositive(a: Int, b: Int) = 
   require (a > 0 && b > 0, a + b)

有一部分scala.Predef ,所以它们总是包含在内。 参数( a+b在本例中)通过名称传递,因此,如果条件不为真,将只被执行。

requires总是被激活,如果你希望能够停用它,你可以让它assert过,如:

assert(a > 0 && b > 0, a + b)


文章来源: Functional assertion in Scala