当我匹配案例类的值时,例如:
sealed abstract class Op
case class UOp[T, K](f: T => K) extends Op
case class BOp[T, Z, K](f: (T, Z) => K) extends Op
像这样:
def f(op: Op): Int =
op match
{
case BOp(g) => g(1,2)
case UOp(g) => g(0)
}
编译器将其推断为
val g: (Nothing, Nothing) => Any
val g: Nothing => Any
为什么我没有这样的类型?是因为JVM类型擦除吗?有没有优雅的方法来匹配函数与变量?
答案 0 :(得分:1)
我提出了这种“hackish”解决方案,也许还有其他方法或更简洁的方法可以做到这一点,而不依赖于反射。
定义一些将处理各种args的部分函数:
scala> val f: PartialFunction[Any, String] = { case (x: Int, y: String) => y * x }
f: PartialFunction[Any,String] = <function1>
scala> val g: PartialFunction[Any, String] = { case x: Int => x.toString }
g: PartialFunction[Any,String] = <function1>
scala> def h: PartialFunction[Any, BigDecimal] = { case (a: Int, b: Double, c: Long) => BigDecimal(a) + b + c }
h: PartialFunction[Any,BigDecimal]
scala> val l: List[PartialFunction[Any, Any]] = f :: g :: h :: Nil
l: List[PartialFunction[Any,Any]] = List(<function1>, <function1>, <function1>)
检查哪些功能可以处理不同的输入:
scala> l.map(_.isDefinedAt(1))
res0: List[Boolean] = List(false, true, false)
scala> l.map(_.isDefinedAt((1, "one")))
res1: List[Boolean] = List(true, false, false)
给定输入查找并应用函数:
scala> def applyFunction(input: Any): Option[Any] = {
| l find (_.isDefinedAt(input)) map (_ (input))
| }
applyFunction: (input: Any)Option[Any]
scala> applyFunction(1)
res1: Option[Any] = Some(1)
scala> applyFunction((2, "one"))
res2: Option[Any] = Some(oneone)
scala> applyFunction("one")
res3: Option[Any] = None
scala> applyFunction(1, 1.1, 9L)
res10: Option[Any] = Some(11.1)
这看起来非常不安全,必须有更好的方法来做到这一点。
我认为磁铁模式应该以更安全的方式处理这个问题。