我是斯卡拉的新手,在研究模式匹配部分时,我感到困惑。
val hd::tail = List(1,2,3,4,5)
执行此代码后,hd将为Int = 1,tail将为List [Int] = List(2,3,4,5)。 这段代码等于:
val ::(hd,tail) = List(1,2,3,4,5)
我了解到这段代码是模式匹配,实际上它调用了unapply方法。 但是当我以这种方式编写代码时,编译错误:
val result = ::.unapply(List(1,2,3,4,5))
它表示方法参数类型不匹配。 “::”的unapply方法需要“:: [?]”
有谁知道原因?
答案 0 :(得分:4)
类型不匹配错误是因为::.unapply
采用::[T]
的实例而不是更通用类型List[T]
的实例。
Scala会根据实际类型自动添加匹配项。
换句话说,我的理解是当你这样做时:
val list = List(1,2,3,4,5)
val hd::tail = list
编译器生成类似于此的东西:
val list = List(1,2,3,4,5)
val (hd, tail) =
::.unapply(
// First match to test against input type
// (necessary as the static type of `list` is `List[Int]`
// so we don't know until runtime if it is an instance of `::[Int]`
// or an instance of `Nil`)
list match {
case nonEmptyList: ::[Int] => nonEmptyList
case _ => throw new MatchError
}
) match { // Second match to test against result of `::`.unapply
case Some( result ) => result
case _ => throw new MatchError
}
答案 1 :(得分:1)
您拥有的方法签名不正确。 ::
是一个案例类,因此取消应用::
的实例。这里有一些更接近你可能正在寻找的东西,虽然我通常不会在代码中调用unapply
,因为它是在模式匹配场景中完成的:
//Note the type returned by unapply
val unappliedOption:Option[(Int, List[Int])] = ::.unapply(::(1, List(2, 3, 4, 5)))
val (hd, tail) = unappliedOption.getOrElse((1, Nil))
在模式匹配中unapply
会自动为您调用。另请注意,::
是非空列表,但仍会返回option
。因此,对于List
的实例,我们有两个选项::
或Nil
:
List(1, 2, 3, 4, 5) match {
case hd :: tail => println(hd, tail) // calls ::.unapply and returns hd tail if the option is Some
case hd => println(hd) //Default case Nil
}