【问题标题】:Function type definition and type erasure in ScalaScala中的函数类型定义和类型擦除
【发布时间】:2011-02-25 16:16:24
【问题描述】:

给定以下类型和实例:

type operation = (Int, Int) => Int
def add: operation = _ + _

如果我尝试匹配 case 语句中的操作,Scala 会抱怨由于类型擦除导致未检查的输入:

for (a <- elements) a match {
  case o: operation => // do stuff
}

有没有办法实现这种基于函数的类型,同时在 case 语句中对擦除友好?

注意,这类似于this thread。

【问题讨论】:

  • 请注意,这个问题与其他链接线程并不特别相似,因为该问题不涉及类型擦除。

标签: scala


【解决方案1】:

处理类型擦除的一种简单方法是创建一个未参数化的类。它并不完美,但它有效。让它成为一个扩展 Function2 的 case 类,直接使用或在模式匹配中使用都不会太笨重

scala> case class Operation(f : (Int,Int) => Int) extends ((Int,Int) => Int) {
     | def apply(x : Int, y : Int) = f(x,y)                                   
     | }
defined class Operation

scala> def add = Operation(_ + _)                                             
add: Operation

scala> val y = add(7,3)
y: Int = 10

scala> val elements = List(1, add, 2)
elements: List[Any] = List(1, <function2>, 2)

scala> for (a <- elements) yield a match {        
     | case Operation(f) => f(1,2)        
     | case x : Int => x
     | }
res0: List[Int] = List(1, 3, 2)

限制是您必须在丢失类型之前“装箱”操作,而不是之后。此外,您最终会为每个具体函数类型提供一个类。

另一个可以说更好的解决方案是不丢失类型信息。使用 Either 来保留静态类型信息。

scala> val elements : List[Either[Int, (Int, Int) => Int]] = List(Left(1), Right(_ + _), Left(2))
elements: List[Either[Int,(Int, Int) => Int]] = List(Left(1), Right(<function2>), Left(2))

scala> for (a <- elements) yield a match {
     | case Right(f) => f(1,2)            
     | case Left(x) => x                  
     | }

res1: List[Int] = List(1, 3, 2)

这里的限制是,如果您的 List 可以有超过 2 种类型,它就会变得笨拙。但它有效地避免了强制 Scala 成为动态类型语言,这与之前的解决方案不同。

【讨论】:

    【解决方案2】:

    如果您可以将a 包装成Option,那么这将起作用:

    scala> val a:Option[Any] = Some(add)
    a: Option[Any] = Some(<function2>)
    
    scala> a match { case o:Some[operation] => println ("found"); case _ => }
    found
    

    【讨论】:

      猜你喜欢
      • 2012-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多