scala 模式匹配序列理解的惯用方法是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11503033/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 04:21:36  来源:igfitidea点击:

What is the idiomatic way to pattern match sequence comprehensions?

scalapattern-matchingfor-comprehension

提问by letmaik

val x = for(i <- 1 to 3) yield i
x match {
    case 1 :: rest => ... // compile error
}

constructor cannot be instantiated to expected type; found : collection.immutable.::[B] required: scala.collection.immutable.IndexedSeq[Int]

构造函数无法实例化为预期类型;发现:collection.immutable.::[B] 需要:scala.collection.immutable.IndexedSeq[Int]

This is the same problem as MatchError when match receives an IndexedSeq but not a LinearSeq.

当 match 接收到 IndexedSeq 而不是 LinearSeq 时,这与MatchError 的问题相同。

The question is, how to do it right? Adding .toListeverywhere doesn't seem right. And creating an own extractor which handles every Seq(as described in the answer of the other question) would lead to a mess if everybody would do it...

问题是,如何做才是正确的?.toList到处添加似乎不正确。Seq如果每个人都这样做,那么创建一个自己的提取器来处理每个(如另一个问题的答案中所述)会导致一团糟......

I guess the question is, why can't I influence what the return type of sequence comprehensions is, or: why isn't such a generalized Seqextractor part of the standard library?

我想问题是,为什么我不能影响序列推导式的返回类型是什么,或者:为什么Seq标准库中没有这种通用提取器的一部分?

回答by oxbow_lakes

Well, you can pattern-match any sequence:

好吧,您可以对任何序列进行模式匹配:

case Seq(a, b, rest @ _ *) =>

For example:

例如:

scala> def mtch(s: Seq[Int]) = s match { 
  |      case Seq(a, b, rest @ _ *) => println("Found " + a + " and " + b)
  |      case _ => println("Bah") 
  |    }
mtch: (s: Seq[Int])Unit

Then this will match any sequence with more than (or equal to) 2 elements

然后这将匹配具有多于(或等于)2 个元素的任何序列

scala> mtch(List(1, 2, 3, 4))
Found 1 and 2

scala> mtch(Seq(1, 2, 3))
Found 1 and 2

scala> mtch(Vector(1, 2))
Found 1 and 2

scala> mtch(Vector(1))
Bah

回答by Roman Kazanovskyi

One more solution for Vector in REPL:

REPL 中 Vector 的另一种解决方案:

Vector() match {
    case a +: as => "head + tail"
    case _       => "empty"  
}
 res0: String = "empty"

Vector(1,2) match {
  case a +: as => s"$a + $as"
  case _      => "empty"  }
res1: String = 1 + Vector(2)