gpt4 book ai didi

Scala 模式匹配与析取不起作用

转载 作者:行者123 更新时间:2023-12-02 06:34:27 25 4
gpt4 key购买 nike

我正在学习 Scala,但不明白为什么以下内容不起作用。

我想重构一个(经过测试的)mergeAndCount 函数,它是计数倒置算法的一部分,以利用模式匹配。这是未重构的方法:

def mergeAndCount(b: Vector[Int], c: Vector[Int]): (Int, Vector[Int]) = {
if (b.isEmpty && c.isEmpty)
(0, Vector())
else if (!b.isEmpty && (c.isEmpty || b.head < c.head)) {
val (count, r) = mergeAndCount(b drop 1, c)
(count, b.head +: r)
} else {
val (count, r) = mergeAndCount(b, c drop 1)
(count + b.length, c.head +: r)
}
}

这是我重构的方法 mergeAndCount2。哪个工作正常。

def mergeAndCount2(b: Vector[Int], c: Vector[Int]): (Int, Vector[Int]) = (b, c) match {
case (Vector(), Vector()) =>
(0, Vector())
case (bh +: br, Vector()) =>
val (count, r) = mergeAndCount2(br, c)
(count, bh +: r)
case (bh +: br, ch +: cr) if bh < ch =>
val (count, r) = mergeAndCount2(br, c)
(count, bh +: r)
case (_, ch +: cr) =>
val (count, r) = mergeAndCount2(b, cr)
(count + b.length, ch +: r)
}

但是如您所见,第二种和第三种情况是重复代码。因此,我想使用这样的析取将它们组合起来:

  case (bh +: br, Vector()) | (bh +: br, ch +: cr) if bh < ch =>       
val (count, r) = mergeAndCount2(br, c)
(count, bh +: r)

这给了我一个错误(在 case 行):illegal variable in pattern alternative

我做错了什么?

非常感谢任何帮助(包括样式)。

更新:感谢您的建议,这里是我的结果:

@tailrec
def mergeAndCount3(b: Vector[Int], c: Vector[Int], acc : (Int, Vector[Int])): (Int, Vector[Int]) = (b, c) match {
case (Vector(), Vector()) =>
acc
case (bh +: br, _) if c.isEmpty || bh < c.head =>
mergeAndCount3(br, c, (acc._1, acc._2 :+ bh))
case (_, ch +: cr) =>
mergeAndCount3(b, cr, (acc._1 + b.length, acc._2 :+ ch))
}

最佳答案

当使用管道符 (|) 进行模式匹配时,您不允许绑定(bind)除通配符 (_) 以外的任何变量。

这很容易理解:在您的case 主体中,bhbr 的实际类型是什么,例如,如果你的两个备选方案匹配不同的类型?

编辑 - 来自 scala 引用:

8.1.11 Pattern Alternatives Syntax: Pattern ::= Pattern1 { ‘|’ Pattern1 } A pattern alternative p 1 | . . . | p n consists of a number of alternative patterns p i . All alternative patterns are type checked with the expected type of the pattern. They may no bind variables other than wildcards. The alternative pattern matches a value v if at least one its alternatives matches v.

在第一条评论后编辑 - 你可以使用通配符来匹配这样的内容,例如:

try {
...
} catch {
case (_: NullPointerException | _: IllegalArgumentException) => ...
}

关于Scala 模式匹配与析取不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23407959/

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