是否可以在scala中模式匹配函数?特别是函数的返回类型。
这是一个例子。如果函数的返回类型是Shoe或Bag,我正在尝试打印Shoe。
object Test extends App {
trait ProductItem {
val name: String
val price: Int
}
case class Product(partialPerson: (String) => ProductItem)
case class Shoe(name: String)(val price: Int) extends ProductItem
case class Bag(name: String)(val price: Int) extends ProductItem
val shoe = Shoe("nike")(_)
val bag = Bag("addidas")(_)
def printType(shoe: (Int) => ProductItem): Unit = {
shoe match {
case isShoe: ((Int) => Shoe) =>
println("Is a shoe")
case isBag: ((Int) => Bag) =>
println("Is a bag")
}
}
printType(shoe)
printType(bag)
}
输出:
是鞋子
是鞋子
预期输出:
是鞋子
是一个包
答案 0 :(得分:5)
这是由编译时的类型擦除引起的:
<console>:17: warning: non-variable type argument Bag in type pattern Int => Bag is unchecked since it is eliminated by erasure
您可以使用TypeTags:
解决此问题def printType[T](shoe: (Int) => T)(implicit tag: TypeTag[T]): Unit = {
shoe match {
case isShoe if tag.tpe =:= typeOf[Shoe]=>
println("Is a shoe")
case isBag if tag.tpe =:= typeOf[Bag] =>
println("Is a bag")
}
}
答案 1 :(得分:2)
编译此代码时,您会收到编译器警告,以解释问题 -
警告:(20,25)非变量类型参数c.n.p.Shoe in type 模式Int =&gt; s.n.p.Shoe是不受限制的,因为它被淘汰了 擦除 case isShoe :( Int =&gt; Shoe)=&gt; ^
围绕它的可能解决方案 -
def printType[T <: ProductItem : ClassTag](item: Int => T): Unit = {
implicitly[ClassTag[T]] match {
case ClassTag(s) if s == classOf[Shoe] =>
println("Is a shoe")
case ClassTag(b) if b == classOf[Bag] =>
println("Is a bag")
}
}
要理解这个解决方案,您必须熟悉隐式参数&amp; ClassTag类型。