Scala中的功能断言 [英] Functional assertion in Scala

查看:145
本文介绍了Scala中的功能断言的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is there built-in support for assertions that return a result?

执行此操作非常无效:

  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)

这样,我可以避免使用assert的命令性方面. (后者不编译) 有类似的东西吗?

In this way I can avoid the imperative aspect of asserts. (the latter does not compile) Is anything similar available?

推荐答案

函数式编程(理想情况下)将函数视为纯数学函数.那么,数学上说函数对某些参数不起作用而必须炸毁的方式是什么?

Functional programming treats functions as pure mathematical functions (ideally). So what's the mathematics' way of saying a function doesn't work for some parameters and must blow up ?

部分函数

事实证明,Scala对这个概念有很好的支持:

It turns out that Scala has a pretty good support for this concept: PartialFunction. This is how you would rewrite your code using partial functions:

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

这有几个好处:

如果使用错误的参数调用它,则会抛出MatchError异常.

If you call it with the wrong parameters it will throw a MatchError exception.

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

您实际上可以对函数的域进行采样,以检查某些值是否非常适合作为函数的参数:

You can actually sample the function's domain to check if some values are well suited as arguments for the function:

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

如果您想将该函数应用于某些参数并获得结果或某个指示失败的值,则可以lift使其返回Option

If you would like to apply the function to some arguments and get either a result, or some value indicating failure, you can lift it to return Option

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

您可以将其与其他函数组合以在参数无效的情况下提供后备功能:

You can compose it with other functions to provide fallback in case of invalid arguments:

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

f(-1, 2) => -2147483648

或者以自定义方式处理错误:

Or to treat errors in a custom way:

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.

It works well with the standard lib: see Seq.collect and Seq.collectFirst.

PartialFunction也是正常的一元函数,因此您也继承了所有函数操作.

Also PartialFunction is a normal unary function, so you inherit all the function operation as well.

这是一篇介绍Scala中非常精美的部分函数的文章:

Here is an article explaining very elegantly partial functions in Scala:

Scala部分函数(无博士学位) )

这篇关于Scala中的功能断言的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆