Список элементов, соответствующих их типу - PullRequest
8 голосов
/ 09 июня 2011

У меня есть код, подобный приведенному ниже:

def walkTree(list:List[Command]) {
    list match {
        case Command1::rest => doSomething(); walkTree(rest)
        case Command2::rest => doSomethingElse(); walkTree(rest)
        case Nil => ;
    }
}

Я также знаю, что вы можете сопоставлять шаблоны для определенного типа и назначать переменную одновременно:

try {
    ...
}
catch {
    case ioExc:IOException => ioExc.printStackTrace()
    case exc:Exception => throw new RuntimeException("Oh Noes", e);
}

Есть ли способ объединить оба в что-то вроде ниже:

def walkTree(list:List[Command]) {
    list match {
        case cmd1:Command1::rest => doSomething(); walkTree(rest)
        case cmd2:Command2::rest => doSomethingElse(); walkTree(rest)
        case Nil => ;
    }
}

Или мне нужно извлечь каждый элемент списка перед соответствием?

Ответы [ 2 ]

18 голосов
/ 09 июня 2011

Да, просто используйте круглые скобки, как это (см. Пример ниже):

def walkTree(list:List[Command]) {
    list match {
        case (cmd1:Command1)::rest => doSomething(); walkTree(rest)
        case (cmd2:Command2)::rest => doSomethingElse(); walkTree(rest)
        case Nil => ;
    }
}

Однако, вы не можете использовать foreach для этого:

scala> List(A(1), B(2), A(3), B(4), A(5)).foreach(_ match {
     |     case (a:A) => println("a:" + a)
     |     case (b:B) => println("b:" + b)
     | })
a:A(1)
b:B(2)
a:A(3)
b:B(4)
a:A(5)

Пример:

scala> case class A(val i: Int);
defined class A

scala> case class B(val i: Int);
defined class B

scala> def walkTree(list: List[ScalaObject]) {
     |     list match {
     |         case (a:A)::rest => println("a:" + a); walkTree(rest);
     |         case (b:B)::rest => println("b:" + b); walkTree(rest);
     |         case Nil => ;
     |     }
     | }
walkTree: (list: List[ScalaObject])Unit

scala> walkTree(List(A(1), B(2), A(3), B(4), A(5)))
a:A(1)
b:B(2)
a:A(3)
b:B(4)
a:A(5)
4 голосов
/ 09 июня 2011

Использование foreach, а затем сопоставление с образцом для каждого элемента кажется мне более понятным:

def walkTree(list:List[Command]) {
  list foreach {
    _ match {
      case cmd1:Command1 => doSomething()
      case cmd2:Command2 => doSomethingElse()
      case _ =>
    }
  }
}
...