Это правило, которое unapply всегда будет возвращать Option?

Я пытался создать unapply метод для использования в сопоставлении с образцом, и я попытался заставить его вернуть что-то другое, чем OptionОднако Eclipse показывает это как ошибку. Это правило, которое unapply должен вернуть Option[T]?

РЕДАКТИРОВАТЬ: вот код, который я пытаюсь использовать. Я переключил код из предыдущего раздела так, чтобы unapply возвращает логическое значение

import java.util.regex._

object NumberMatcher {
  def apply(x:String):Boolean = {
    val pat = Pattern.compile("\\d+")
    val matcher = pat.matcher(x)
    return matcher.find
  }

  def unapply(x:String):Boolean = {
    val pat = Pattern.compile("\\d+")
    val matcher = pat.matcher(x)
    return matcher.find
  }
}

object x {
  def main(args : Array[String]) : Unit = {
    val strings = List("geo12","neo493","leo")
    for(val str <- strings) {
      str match {
        case NumberMatcher(group) => println(group)
        case _ => println ("no")
      }
    }
  }
}

Затмение говорит wrong number of arguments for object NumberMatcher, Это почему?

4 ответа

Решение

Если вы хотите вернуть что-то с unapply, верни его внутрь Some, возврате Boolean просто проверяет, может ли совпадение быть сделано или нет.

Вот как переводится шаблон соответствия:

str match { 
  case NumberMatcher(group) => println(group)
  case _ => println("no")
}

Если предположить, NumberMatcher возвращается Option[...], это будет сделать:

val r1 = NumberMatcher.unapply(str)
if (r1 != None) {
  val group = r1.get
  println(group)
} else {
  println("no")
}

Если NumberMatcher возвращает логическое значение, тогда вы можете получить что-то. В этом случае вот что происходит:

str match { 
  case NumberMatcher() => println("yes")
  case _ => println("no")
}

становится

val r1 = NumberMatcher.unapply(str)
if (r1) {
  println("yes")
} else {
  println("no")
}

Обратите внимание, что это очень поверхностное объяснение. Совпадения с примерами могут проверять константы, иметь дополнительные условия защиты, альтернативы, использовать unapply рекурсивно использовать unapplySeqи т. д. Здесь я только показываю очень простое использование для решения конкретного вопроса. Я настоятельно рекомендую поискать более полное объяснение сопоставления с образцом.

Посмотрите на этот пример еще раз. я цитирую

Тип возврата неприменяемого должен быть выбран следующим образом:
* Если это просто проверка, верните логическое значение. Например, даже ()
* Если он возвращает единственное вспомогательное значение типа T, вернуть Option [T]
* Если вы хотите вернуть несколько вложенных значений T1,...,Tn, сгруппируйте их в необязательный кортеж Option[(T1,...,Tn)].

Когда вы определили unapply вернуть Boolean, вы указали, что шаблон не имеет подстановочных знаков для сопоставления (или привязки). Таким образом, утверждение для этого недействительного должно быть case NumberMatcher => println(str)и неправильно указывать переменную для заполнения.

В качестве альтернативы, чтобы сделать case NumberMatcher(group) => println(group) вам нужно определить unapply() возвращать Option[String]

package com.tutorial.extracters
object ExtracterwithBooleanReturnType extends App {
import java.util.regex._
object NumberMatcher {
  def apply(x: String*) = {
    x
  }
  def unapply(x: String): Option[Boolean] = {
    val pat = Pattern.compile("\\d+")
    val matcher = pat.matcher(x)
    return Some(matcher.find)
 }
}

val strings = NumberMatcher("geo12", "neo493", "leo")
for (str <- strings) {
  str match {
  case NumberMatcher(group) => println(group)
  case _ => println("no")
}
}
}

мы можем добиться этого с помощью приведенного выше кода, а также

Другие вопросы по тегам