You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala中case语句里cons运算符及占位符作用解析

Understanding Right-Associative Operators and Underscores in Scala Pattern Matching

Great question—let’s unpack both parts of your confusion clearly, using your findKth1 example as a reference.

1. Why the Cons Operator (::) Works in Case Statements (Pattern Matching)

First, let’s clarify: the :: operator (Scala’s list "cons" operator) isn’t just a regular operator—it’s deeply tied to Scala’s pattern matching mechanism via extractors. Here’s the breakdown:

  • Scala’s List is built using :: as its core constructor. When you write 3 :: 4 :: 5 :: 6 :: Nil, you’re actually calling the right-associative method :: on the tail list (since operators ending with : are right-associative in Scala). So 3 :: List(4,5,6) is equivalent to List(4,5,6).::(3).
  • For pattern matching, Scala supports infix patterns (writing operators in the middle of a pattern). When you use h :: _ or _ :: tail in a case statement, this is shorthand for ::(h, _) or ::(_, tail). The :: companion object implements an unapply method, which is what enables pattern matching: it takes a list and splits it into its head and tail (if the list is non-empty).
  • That’s why case (0, h::_) works: it matches a tuple where the first element is 0, and the second is a non-empty list—extracting the head into h and ignoring the tail (via _).

2. The Role of Underscores (_) in This Code

In your findKth1 function, the underscores serve two related but distinct roles in pattern matching:

  • Wildcard for unused values: When you see h::_ or _::tail, the _ acts as a wildcard. It means "match any value here, but I don’t need to assign it to a variable because I won’t use it in the case body." For example:
    • h::_ matches any non-empty list, captures the head into h, and discards the tail (since we don’t need it for the 0th element case).
    • _::tail matches any non-empty list, discards the head (we don’t care what it is—we just need the tail to recurse on), and captures the tail into tail.
  • Catch-all pattern: The final case _ => uses _ as a catch-all. It matches any input that didn’t fit the previous two cases (like a negative k, or an empty list when k is still positive), triggering the NoSuchElementException.

Note: This is different from the underscore’s role in anonymous functions (e.g., List(1,2,3).map(_ * 2) where _ is a placeholder for the function parameter). In pattern matching, it’s purely a wildcard for values you don’t need to reference.

Your Code Example, Annotated

def findKth1[A](k:Int, l:List[A]):A = (k, l) match {
  case (0, h::_) => h  // _ = ignore the tail; extract head h
  case(k, _::tail) if k > 0 => findKth1(k - 1, tail)  // _ = ignore the head; extract tail
  case _ => throw new NoSuchElementException  // _ = catch all other cases
}

findKth1(2, List(3,4,5,6))  // Returns 5, as expected

内容的提问来源于stack exchange,提问作者Jwan622

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:20:59