2012-11-11 11 views
5
scala> (1,5) == BigInt(12) /% 7 
res3: Boolean = true 

scala> BigInt(12) /% 7 match { 
| case (1,5) => true 
| } 

<console>:9: error: type mismatch; 
found : Int(1) 
required: scala.math.BigInt 
      case (1,5) => true 
       ^

Qualcuno può forse spiegarmi come abbinare il motivo qui?Corrispondenza modello in Scala

risposta

10

match è più specifico di uguaglianza; non puoi essere solo uguale, devi anche avere lo stesso tipo.

In questo caso, BigInt non è un case class e non ha un metodo unapply nel suo oggetto companion, quindi non è possibile abbinarlo direttamente. Il meglio che si possa fare è

BigInt(12) /% 7 match { 
    case (a: BigInt,b: BigInt) if (a==1 && b==5) => true 
    case _ => false 
    } 

o qualche variante di esso (ad esempio case ab if (ab == (1,5)) =>).

In alternativa, è possibile creare un oggetto con un metodo unapply di tipo appropriato:

object IntBig { def unapply(b: BigInt) = Option(b.toInt) } 

scala> BigInt(12) /% 7 match { case (IntBig(1), IntBig(5)) => true; case _ => false } 
res1: Boolean = true 
+0

Il binding a variabili e una guardia è quello che ho fatto. Ho appena pensato che potrebbe forse essere fatto un po 'meglio. Grazie. – marcus

1

Il problema è che 1 e 5 restituito da /% sono BigInt s e quindi non corrispondono letterale Int s anche se equals metodo (chiamato da ==) restituisce true. Questo funziona, ma è un po 'poco elegante:

scala> BigInt(12) /% 7 match { case (x, y) if x == 1 && y == 5 => true } 
res3: Boolean = true 
2

1 e 5 sono Int tipi. La corrispondenza del modello si aspetta un scala.math.BigInt. Quindi, dagli quello dichiarando un paio di val per uno e cinque.

scala> val OneBig = BigInt(1) 
oneBig: scala.math.BigInt = 1 

scala> val FiveBig = BigInt(5) 
fiveBig: scala.math.BigInt = 5 

scala> BigInt(12) /% 7 match { 
    | case (OneBig, FiveBig) => true 
    | } 
res0: Boolean = true 
+3

Questo non funziona! 'oneBig' e' fiveBig' nel pattern sono nuove variabili non correlate a quelle precedentemente definite. Questo può essere cambiato nominandoli con una lettera maiuscola ('OneBig' e' FiveBig') o circondando i nomi con i backtick. –

+0

Grazie. Dimenticato di questo. Per gli interessati, consultare http://stackoverflow.com/questions/4479474/scala-pattern-matching-with-lowercase-variable-name o pagina 317 del libro delle scale. – Brian