Kev*_*ith 15 scala pattern-matching
以下不起作用.
object Foo {
def union(s: Set[Int], t: Set[Int]): Set[Int] = t match {
case isEmpty => s
case (x:xs) => union(s + x, xs)
case _ => throw new Error("bad input")
}
}
Run Code Online (Sandbox Code Playgroud)
错误:未找到:输入xs
如何在一组上进行模式匹配?
Dan*_*ral 19
嗯,类型的x:xs手段,所以它不会工作.但是,唉,你不能模式匹配集,因为集合没有定义的顺序.或者,更实际,因为没有提取器.xxsSet
您可以随时定义自己的:
object SetExtractor {
def unapplySeq[T](s: Set[T]): Option[Seq[T]] = Some(s.toSeq)
}
Run Code Online (Sandbox Code Playgroud)
例如:
scala> Set(1, 2, 3) match {
| case SetExtractor(x, xs @ _*) => println(s"x: $x\nxs: $xs")
| }
x: 1
xs: ArrayBuffer(2, 3)
Run Code Online (Sandbox Code Playgroud)
Set不是case class,也没有unapply方法.
这两件事暗示你不能直接在a上进行模式匹配Set.
(更新:除非你定义自己提取的Set,如丹尼尔正确地显示在他的回答)
你应该找到一个替代方案,我建议使用折叠功能
def union(s: Set[Int], t: Set[Int]): Set[Int] =
(s foldLeft t) {case (t: Set[Int], x: Int) => t + x}
Run Code Online (Sandbox Code Playgroud)
或者,避免使用大多数显式类型注释
def union(s: Set[Int], t: Set[Int]): Set[Int] =
(s foldLeft t)( (union, element) => union + element )
Run Code Online (Sandbox Code Playgroud)
甚至更短
def union(s: Set[Int], t: Set[Int]): Set[Int] =
(s foldLeft t)(_ + _)
Run Code Online (Sandbox Code Playgroud)
这将累积sover 的元素,t逐个添加它们
折页
以下是折叠操作的文档,如果需要参考:
foldLeft[B](z: B)(op: (B, A) ? B): B
Run Code Online (Sandbox Code Playgroud)
将二元运算符应用于起始值以及此集合的所有元素,从左到右.
注意:除非订购了基础集合类型,否则可能会为不同的运行返回不同的结果.或者运算符是关联的和可交换的.
B the result type of the binary operator.
z the start value.
op the binary operator.
returns the result of inserting op between consecutive elements of this set, going left to right with the start value z on the left:
op(...op(z, x_1), x_2, ..., x_n)
where x1, ..., xn are the elements of this set.
Run Code Online (Sandbox Code Playgroud)
首先,您isEmpty将捕获每个,Set因为它是此上下文中的变量。在 Scala 中,常量以大写字母开头,并且仅当此条件成立时才将其视为常量。所以小写字母会将任何分配给Set(isEmpty您在寻找吗EmptySet?)
从这里可以看出,模式匹配对于 s 来说似乎并不是很可取Set。您可能应该显式地将 转换Set为 aList或Seq( toList/ toSeq)
object Foo {
def union(s: Set[Int], t: Set[Int]): Set[Int] = t.toList match {
case Nil => s
case (x::xs) => union(s + x, xs.toSet)
case _ => throw new Error("bad input")
}
}
Run Code Online (Sandbox Code Playgroud)