Scala递归拆分列表方法中val(pre, post)的作用解析问询
解析Scala递归拆分列表中的
val(pre, post)语句 我来给你一步步拆解这段代码里val(pre, post)的作用,先把你给出的完整代码贴出来方便对照:
def splitRecursive[A](n: Int, ls: List[A]): (List[A], List[A]) = (n, ls) match { case (_, Nil) => (Nil, Nil) case (0, list) => (Nil, list) case (n, h :: tail) => { val (pre, post) = splitRecursive(n - 1, tail) (h :: pre, post) } }
先明确函数的核心逻辑
这个函数的目标是把输入列表拆分成两部分:前n个元素组成的列表,和剩下的元素组成的列表,返回的是一个二元组(List[A], List[A])——这是理解val(pre, post)的关键前提。
val(pre, post)到底在做什么?
这行代码是Scala里的元组解构赋值,本质是用模式匹配把递归调用返回的二元组拆成两个独立变量:
splitRecursive(n - 1, tail)会返回一个二元组,比如某次递归返回(List(b,c), List(d,e))val (pre, post)直接把这个二元组的第一个元素赋值给pre,第二个元素赋值给post,相当于帮你省掉了val res = ...; val pre = res._1; val post = res._2这种繁琐的写法。
结合你举的例子走一遍递归流程(n=3,列表List(a,b,c,d,e))
我们跟着调用栈一步步看,就能明白这行代码的实际作用:
- 最外层调用:
splitRecursive(3, List(a,b,c,d,e)),匹配case (n, h::tail),这里h=a,tail=List(b,c,d,e),然后调用splitRecursive(2, List(b,c,d,e)) - 第二层调用:
splitRecursive(2, List(b,c,d,e)),同样匹配case (n, h::tail),h=b,tail=List(c,d,e),调用splitRecursive(1, List(c,d,e)) - 第三层调用:
splitRecursive(1, List(c,d,e)),匹配case (n, h::tail),h=c,tail=List(d,e),调用splitRecursive(0, List(d,e)) - 第四层调用:
splitRecursive(0, List(d,e)),匹配case (0, list),直接返回(Nil, List(d,e)) - 回到第三层:
val (pre, post)把返回的(Nil, List(d,e))拆成pre=Nil,post=List(d,e),然后返回(c::pre, post)也就是(List(c), List(d,e)) - 回到第二层:
val (pre, post)把返回的(List(c), List(d,e))拆成pre=List(c),post=List(d,e),返回(b::pre, post)也就是(List(b,c), List(d,e)) - 回到最外层:
val (pre, post)把返回的(List(b,c), List(d,e))拆成pre=List(b,c),post=List(d,e),返回(a::pre, post)也就是(List(a,b,c), List(d,e))——这正是你想要的结果!
总结val(pre, post)的核心作用
- 接收递归“子问题”的结果:每次递归都是在解决“拆分剩下的列表,取前n-1个元素”的子问题
- 解构结果方便后续处理:把返回的二元组拆成两个变量,让我们可以轻松把当前元素
h拼接到pre的前面(因为递归是从后往前处理元素的,这样拼接才能保持原顺序) - 传递结果逐步构建最终答案:每一层递归的结果都会被上一层拆解、加工,最终组合成完整的拆分结果
内容的提问来源于stack exchange,提问作者user2708013
相关产品推荐
相关产品推荐

