Scala ошибка совпадения

Я попытался заменить мою проверку isInstanceOf совпадением, но она не работает.

В моем методе я делаю чек для дерева node - если это лист - я хочу сразу его вернуть в вектор, если нет - я продолжу этот метод.

Итак, изначально у меня было:

    //code here
    if (common.isInstanceOf[LeafNode]) {
        return Vector(common.asInstanceOf[LeafNode].data)
    }
    //code here

то я попытался заменить его на:

    //code here
     common match {
        case leaf: LeafNode => return Vector(leaf.data)
    }
    //code here

но я получаю scala.MatchError.

Ответы

Ответ 1

Вы получаете MatchError в случае, если ваш common не является LeafNode. Ваши выражения if и match не эквивалентны. Я думаю, что самый прямой способ сделать их эквивалентными:

common match {
  case leaf: LeafNode => return Vector(leaf.data)
  case _ =>
}

Но я бы рекомендовал посмотреть на весь блок кода, и разработка более функционального способа выполнить эту работу. То есть без return посередине. Помните, что совпадение является выражением, так что возможно что-то подобное:

def foo = {
  //code here
  common match {
    case leaf: LeafNode => Vector(leaf.data)
    case notLeaf: Branch => //code here
  }
}

Ответ 2

Проблема в том, что множество случаев в вашем блоке match не является исчерпывающим; если common ничего, кроме a LeafNode, будет выбрано a MatchError. Вы можете решить эту проблему, если у вас есть такой случай:

common match {
  case leaf: LeafNode => return Vector(leaf.data)
  ... // other cases
  case other => ... // what to do if nothing else matches
}

Это аналогично случаю default в инструкции Java switch. Случай other называется "неопровержимым шаблоном", потому что он не имеет характеристик; он не требует определенного типа или конструктора, поэтому он всегда будет соответствовать всем, что попадает на него. Имя переменной не должно быть other, это может быть все, что угодно, или даже _... на самом деле вам не нужно связывать новую переменную здесь, так как она будет идентична common.

В точке стиля это обычно плохая форма для размещения операторов return внутри блока match; весь блок является выражением, которое оценивает один из его случаев, поэтому просто возвращаем все выражение. Кроме того, вам не нужно использовать ключевое слово return вообще, поскольку в результате будет использовано последнее выражение в определении функции.