简体   繁体   English

如何在Scala中对功能进行模式匹配?

[英]How to pattern match a function in Scala?

Is it possible to pattern match functions in scala ? 是否可以在scala中对匹配函数进行模式化? Specially the return type of the function. 特别是函数的返回类型。

Here is an example. 这是一个例子。 I'm trying to print Shoe if the function's return type is Shoe or Bag otherwise. 如果函数的返回类型为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)
}

Output: 输出:
Is a shoe 是鞋子
Is a shoe 是鞋子

Expected output: 预期产量:
Is a shoe 是鞋子
Is a bag 是一个包

This is caused by the type erasure in compile time: 这是由编译时的类型擦除引起的:

<console>:17: warning: non-variable type argument Bag in type pattern Int => Bag is unchecked since it is eliminated by erasure

You can solve it by using TypeTags : 您可以使用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")
    }
}

When compiling this code you get a compiler warning tha explains the problem - 编译此代码时,您会收到一个编译器警告,解释了该问题-

Warning:(20, 25) non-variable type argument cnpShoe in type pattern Int => cnpShoe is unchecked since it is eliminated by erasure case isShoe: (Int => Shoe) => ^ 警告:(20,25)类型模式为Int => cnpShoe的非变量类型参数cnpShoe未被选中,因为通过擦除情况isShoe消除了它((Int => Shoe)=> ^

a possible solution around it - 可能的解决方案-

  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")
    }
  }

To understand this solution you'll have to be familiar with implicit parameters & ClassTag type. 要了解此解决方案,您必须熟悉隐式参数和ClassTag类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM