【问题标题】:Scala: How can I match only the first two elements of an arbitrary ListScala:如何仅匹配任意列表的前两个元素
【发布时间】:2014-09-29 17:43:09
【问题描述】:

我正在尝试匹配列表的前两个元素,但是,它不会接受任意长度的列表。以下代码失败。

  def demoCases() = {
    def actor1 = new Actor[Employee] {}
    def actor2 = new Actor[Employee] {}
    def actor3 = new Actor[Animal] {}

    var actors = List(actor1, actor2, actor3);
    println();
    actors match {
      case (_: Employee) :: (_: Employee) :: tail
        => {println("nice 2  employees to start with ")};

      case Nil
        => {println("no match")}
    }

例外:

Exception in thread "main" scala.MatchError: List(.....)

如何指定只有列表的两个元素first需要匹配这个表达式?

【问题讨论】:

  • => 后面不需要 { }

标签: list scala generics pattern-matching match


【解决方案1】:

只需将case Nil 替换为case _ => println("no match")_ 作为模式意味着“匹配任何东西”。但请注意,您的第一种情况要求列表的前两个元素是 Employees,而不是 Actors。

【讨论】:

  • 最初的目标是匹配泛型类型(即匹配雇员、雇员但不匹配雇员、动物)。那可能吗 ?它似乎无法匹配泛型类型。看来stackoverflow.com/questions/16056645/… 有更合适的解决方案。
  • 其实,再进一步看,我的初衷,即通过泛型匹配,可能根本不可能?
  • 是的,一般来说是不可能的。如果您控制Actor 的定义,则有一些解决方法,如您链接的问题中所述。
【解决方案2】:

由于类型擦除,以下内容不起作用(Alexey Romanov 指出)

case (_: Actor[Employee]) :: (_: Actor[Employee]) :: tail

因此,如果不重组代码,我想不出任何方法来做你想做的事。例如,如果您以某种方式使Employee 成为Actor 的成员,并使Actor 成为案例类,您可以这样做

case Actor(_: Employee) :: Actor(_: Employee) :: tail

【讨论】:

  • 由于类型擦除,这将无法正常工作。它只会检查元素是Actor[_],而不是Actor[Employee]
  • @AlexeyRomanov 感谢您的反馈。这是一个诱人且有启发性的答案(因此是赞成票),但不是精确的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-13
  • 1970-01-01
  • 1970-01-01
  • 2013-04-03
  • 1970-01-01
  • 2015-08-06
  • 1970-01-01
相关资源
最近更新 更多