Scala中strStr函数collectFirst里`needle`反引号作用解析
Scala模式匹配中反引号的作用解析
问题代码
def strStr(haystack: String, needle: String): Int = { if (needle == "") { 0 } else { haystack .sliding(needle.length) .zipWithIndex .collectFirst({ case (`needle`, y) => y }) .getOrElse(-1) } }
疑问
在collectFirst方法的case语句中,为何要将参数needle用反引号包裹成`needle`?去掉反引号后为何无法正常工作?
解答
1. 不带反引号的case (needle, y)的本质
Scala的模式匹配规则里,直接写变量名会创建新的局部变量绑定。也就是说,当你写case (needle, y)时,这里的needle是一个全新的局部变量,它会匹配滑动窗口输出的任意字符串,把当前窗口的内容赋值给这个变量后,直接返回对应的索引y。
这种情况下,不管函数参数里的needle是什么值,代码都会直接返回第一个滑动窗口的索引0,完全达不到“查找目标字符串首次出现位置”的目的。
2. 带反引号的case (`needle`, y)的作用
用反引号包裹变量名时,Scala会把它当作外部已存在的变量引用,而不是创建新变量。也就是说,这里的`needle`指向的是函数参数里传入的目标字符串,模式匹配会检查当前滑动窗口的字符串是否和这个外部变量的值相等,只有匹配成功时才会返回对应的索引y。
举个实际例子:
- 假设
haystack = "hello",needle = "ll"- 不带反引号:第一个滑动窗口是
"he",会被case (needle, y)匹配,直接返回索引0,结果错误。 - 带反引号:会跳过前两个窗口
"he"、"el",直到匹配到"ll"(对应索引2)才返回,结果正确。
- 不带反引号:第一个滑动窗口是
3. 总结
反引号在Scala模式匹配中的核心作用,就是区分“创建新变量绑定”和“引用外部已有变量”。当你需要在模式中匹配外部变量的值时,必须用反引号把变量名包裹起来,否则就会变成创建新变量,完全偏离预期逻辑。
内容的提问来源于stack exchange,提问作者Anastasia
相关产品推荐
相关产品推荐

