以下是行不通的。
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")
}
}
错误:未找到:XS型
我怎样才能模式匹配在一组?
以下是行不通的。
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")
}
}
错误:未找到:XS型
我怎样才能模式匹配在一组?
那么, x:xs
手段x
型的xs
,所以这是行不通的。 但是,唉,你不能模式匹配套,因为套没有定义的顺序。 或者,更务实的态度,因为有上没有提取Set
。
你总是可以定义自己,虽然:
object SetExtractor {
def unapplySeq[T](s: Set[T]): Option[Seq[T]] = Some(s.toSeq)
}
例如:
scala> Set(1, 2, 3) match {
| case SetExtractor(x, xs @ _*) => println(s"x: $x\nxs: $xs")
| }
x: 1
xs: ArrayBuffer(2, 3)
Set
不是case class
,没有一个unapply
方法。
这两件事意味着你不能直接模式匹配上一Set
。
( 更新 :除非你定义自己的提取 Set
,如丹尼尔正确地显示在他的回答)
你应该找到一个替代方案,我建议使用折叠功能
def union(s: Set[Int], t: Set[Int]): Set[Int] =
(s foldLeft t) {case (t: Set[Int], x: Int) => t + x}
或者,避免了最明确的类型注释
def union(s: Set[Int], t: Set[Int]): Set[Int] =
(s foldLeft t)( (union, element) => union + element )
或者更短
def union(s: Set[Int], t: Set[Int]): Set[Int] =
(s foldLeft t)(_ + _)
这将积累的元素s
在t
,一个逐一添加
折页
下面是文档的折叠操作中,如果需要的话以供参考:
foldLeft[B](z: B)(op: (B, A) ⇒ B): B
应用二元运算符的初始值和该组中的所有元素,从左到右。
注:可能会有不同的结果不同的运行,除非底层集合类型是有序的。 或操作员是联想和交换。
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.
首先,你isEmpty
会抓住每一个Set
,因为它在这方面的一个变量。 常量开始在Scala中的大写字母而如果这个条件成立被视为只为常数。 所以小写将指派任何Set
到isEmpty
(您寻找的EmptySet
?)
正如所看到这里 ,似乎是模式匹配不是很理想Set
秒。 你应该明确地转换Set
到List
或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")
}
}
这是我能想出:
object Contains {
class Unapplier[T](val t: T) {
def unapply(s: Set[T]): Option[Boolean] = Some(s contains t)
}
def apply[T](t: T) = new Unapplier(t)
}
object SET {
class Unapplier[T](val set: Set[T]) {
def unapply(s: Set[T]): Option[Unit] = if (set == s) Some(Unit) else None
}
def apply[T](ts: T*) = new Unapplier(ts.toSet)
}
val Contains2 = Contains(2)
val SET123 = SET(1, 2, 3)
Set(1, 2, 3) match {
case SET123() => println("123")
case Contains2(true) => println("jippy")
case Contains2(false) => println("ohh noo")
}
t match {
case s if s.nonEmpty => // non-empty
case _ => // empty
}