2016-02-28 64 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") 
}