gpt4 book ai didi

scala - PartialFunction 如何处理 Scala 中的未定义值?

转载 作者:行者123 更新时间:2023-12-01 11:29:18 24 4
gpt4 key购买 nike

我定义了 PartialFunction 的 2 个版本在斯卡拉。

  val doubleEvens1: PartialFunction[Int, Int] = {
case x if x % 2 == 0 => x * 2
}

val doubleEvens2 = new PartialFunction[Int, Int] {
override def isDefinedAt(x: Int): Boolean = x % 2 == 0

override def apply(v1: Int): Int = v1 * 2
}

和一个列表:
val list = List(1, 2, 3, 4, 5)

但是,对于未定义的值,它们的行为有所不同:
// doubleEvens1
println(doubleEvens1.isDefinedAt(3)) // false
println(list.collect(doubleEvens1)) // List(4, 8)
println(doubleEvens1(3)) // scala.MatchError
println(list.map(doubleEvens1)) // scala.MatchError

// doubleEvens2
println(doubleEvens2.isDefinedAt(3)) // false
println(list.collect(doubleEvens2)) // List(4, 8)
println(doubleEvens2(3)) // 6
println(list.map(doubleEvens2)) // List(2, 4, 6, 8, 10)

我猜 doubleEvens1应该是合理的,因为它符合数学定义。但是是 doubleEvens2的行为故意设计的?或者我在代码片段中遗漏了什么?

最佳答案

如果您实现自己的 apply方法,不检查 isDefinedAt ,那么显然您可以使用任何输入调用该方法而不会引发异常。这在文档中明确说明:

It is the responsibility of the caller to call isDefinedAt before calling apply, because if isDefinedAt is false, it is not guaranteed apply will throw an exception to indicate an error condition. If an exception is not thrown, evaluation may result in an arbitrary value.



碰巧从模式匹配创建的部分函数将调用 isDefinedAt来自其 apply方法实现并抛出异常。

所以如果你想复制这种行为,你必须这样做:
val doubleEvens2 = new PartialFunction[Int, Int] {
override def isDefinedAt(x: Int): Boolean = x % 2 == 0

override def apply(x: Int): Int =
if (isDefinedAt(x)) x * 2 else throw new MatchError(x.toString)
}

当然,缺点是某些代码( isDefined )可能会被多次调用,如 this question 中所述。 .

关于scala - PartialFunction 如何处理 Scala 中的未定义值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34449912/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com