7 Stimmen

Überschreiben der unapply-Methode

Ich habe eine Klasse aus einer Bibliotheksklasse und möchte die Methode unapply überschreiben, um die Anzahl der zu übergebenden Parameter zu reduzieren, damit ich sie bei der Musterabgleichung verwenden kann. Ich mache das so:

object ws1 {
  // eine Bibliotheksklasse
  case class MyClass(a: Int, b: String, c: String, d: Double /* und viele mehr*/)

  // mein erstelltes Objekt, um unapply von Klasse MyClass zu überschreiben
  object MyClass {
    def unapply(x: Int) = Some(x)
  }

  val a = new MyClass(1, "2", "3", 55.0 /* und viele mehr*/)
  a match {
    case MyClass(x /*nur der erste ist wichtig*/) => x  // java.io.Serializable = (1,2,3,55.0)
    case _ => "nein"
  }
}

Aber ich möchte, dass es nur 1 zurückgibt. Was ist falsch daran?

8voto

Karol S Punkte 8701
case class MyClass(a: Int, b: String, c: String, d: Double /* und viele weitere*/)
object MyClassA {
   def unapply(x: MyClass) = Some(x.a)
}

val a = new MyClass(1, "2", "3", 55.0 /* und viele weitere*/)

a match {
    case MyClassA(2) => ??? // passt nicht
    case MyClassA(1) => a   // passt
    case _ => ??? 
}

Sie können Ihre benutzerdefinierte unapply-Methode nicht im MyClass-Objekt definieren, da sie einen MyClass-Parameter enthalten müsste, und es gibt bereits eine solche Methode dort - automatisch generiert für die Fallklasse. Daher müssen Sie es in einem anderen Objekt definieren (MyClassA in diesem Fall).

Das Pattern-Matching in Scala nimmt Ihr Objekt und wendet mehrere unapply- und unapplySeq-Methoden darauf an, bis es Some mit Werten erhält, die mit den im Muster angegebenen übereinstimmen.
MyClassA(1) passt zu a, wenn MyClassA.unapply(a) == Some(1).

Hinweis: Wenn ich case m @ MyClassA(1) => schreiben würde, wäre die Variable m vom Typ MyClass.

Bearbeiten:

a match {
    case MyClassA(x) => x  // x ist ein Int, gleich a.a
    case _ => ??? 
}

1voto

Shadowlands Punkte 14844

Ich würde das überladene unapply verwerfen und einfach folgendes für das Match verwenden:

a match {
  case MyClass(x, _, _, _) => x  // Ergebnis ist: 1
  case _ => "no"
}

BEARBEITEN :

Wenn Sie wirklich die zusätzlichen Unterstriche vermeiden möchten, denke ich, dass Sie etwas wie folgt betrachten müssen:

a match {
  case x:MyClass => x.a
  case _ => "no"
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X