2016-02-28 62 views
4

代碼:提取衝突

case class Division(val number: Int) { 
// def unapply(divider: Int): Option[(Int, Int)] = if (number % divider == 0) Some(number/divider, 0) else None 
// def unapply(divider: Double): Boolean = number % divider.toInt == 0 
    def unapplySeq(x: Float): Option[Seq[Int]] = { 
     val seq = (3 to 10).map(i => i * x.toInt) 
     println(seq) 
     Some(seq) 
    } 
    } 



    val divisionOf15 = Division(15) 

// val y = 5 match { 
// case divisionOf15(z, w) => println(s"$z, $w") 
// case _ => println(s"Not divisible") 
// } 

// val z = 5.0 match { 
// case divisionOf15() => println("Divisible") 
// case _ => println("Not divisible") 
// } 

    val u = 5.0F match { 
    case divisionOf15(f1, f2, _*) => println(s"$f1, $f2") 
    } 

如果我取消這些行:

// def unapply(divider: Int): Option[(Int, Int)] = if (number % divider == 0) Some(number/divider, 0) else None 
// def unapply(divider: Double): Boolean = number % divider.toInt == 0 

錯誤編譯期間作物起來:

Star pattern must correspond with varargs or unapplySeq 
    case divisionOf15(f1, f2, _*) => println(s"$f1, $f2") 
     ^

如果我取消這條線:

// def unapply(divider: Int): Option[(Int, Int)] = if (number % divider == 0) Some(number/divider, 0) else None 

我得到兩個錯誤:

scrutinee is incompatible with pattern type; 
found : Int 
required: Float 
    case divisionOf15(f1, f2, _*) => println(s"$f1, $f2") 
        ^
Star pattern must correspond with varargs or unapplySeq 
    case divisionOf15(f1, f2, _*) => println(s"$f1, $f2") 
     ^

我做得不對或這是一個錯誤?這些提取器顯得無辜,不應相互衝突。

+1

不可超載 –

+1

如果你仔細想想它,如果你同時擁有'unapply'和'unapplySeq',它怎麼能工作?編譯器不知道你正在嘗試使用哪一個。 –

回答

5

language specification沒有提及unapplyunapplySeq的同時存在。這暗示了他們的互斥,雖然:

具有名爲unapplyunapplySeq

成員方法的對象...

如果提取物X沒有一個unapply方法,但它的確定義爲unapplySeq方法

This blog也指出:

注:如果雙方不應用和unapplySeq只能定義不應用使用。

因此,無論定義不同的提取(它似乎並不明顯,我到過載你的情況的定義!),或者用unapply去:

case class Division(val number: Int) { 
    def unapply(divider: Int): Option[(Int, Int)] = 
    if (number % divider == 0) Some(number/divider, 0) else None 

    def unapply(divider: Double): Boolean = number % divider.toInt == 0 

    def unapply(x: Float): Option[Seq[Int]] = { 
    val seq = (3 to 10).map(i => i * x.toInt) 
    println(seq) 
    Some(seq) 
    } 
} 

val u = 5.0F match { 
    case divisionOf15(Seq(f1, f2, _*)) => println(s"$f1, $f2") 
}