首页 文章

Scala模式与清单匹配

提问于
浏览
7

This great daily Scala article描述了如何克服匹配中的类型擦除 . 我正在尝试应用该技术来转换参数化类型的IndexesSeq,但匹配失败 . 为什么会这样,我该如何解决?

object Example extends App{
    class TableColumn[T](
        val values: IndexedSeq[T], 
        val name: Option[String] = None
    )(implicit val m: Manifest[T])

    class Def[C](implicit desired : Manifest[C]) {
        def unapply[X](c : X)(implicit m : Manifest[X]) : Option[C] = {
            //println("m.toString+", "+desired.toString)
            def sameArgs = desired.typeArguments.zip(m.typeArguments).forall {
                case (desired,actual) => desired >:> actual
            }
            if (desired >:> m && sameArgs) Some(c.asInstanceOf[C])
            else None
         }
    }

    val IntTableColumn = new Def[TableColumn[Int]]
    val DoubleTableColumn = new Def[TableColumn[Double]]

    class Analysis(data: IndexedSeq[TableColumn[_]]){
        val transformedData = data.map{_ match{
            case IntTableColumn(tc) => println("Column of Int! "+ tc)
            case DoubleTableColumn(tc) => println("Column of Double! "+ tc)
            case _ => println("no match")
        }}
    }

    new Analysis(IndexedSeq(
            new TableColumn(IndexedSeq(1,2,3)),
            new TableColumn(IndexedSeq(1.0,2.0,3.0))
    ))
}

如果我取消注释Def中的行,那么我会看到诸如的行

prototype.Example$TableColumn[_ <: Any], prototype.Example$TableColumn[Int]

建议Analysis构造函数中的_是问题,但我不知道还有什么可以放在那里 .

1 回答

  • 1

    感谢雷克斯克尔的评论,我拼凑了一些我觉得有用的东西 . 它可能更优雅/更普遍,但它似乎现在完成工作:

    object Example extends App{
        class TableColumn[T](
                val values: IndexedSeq[T], 
                val name: Option[String] = None
        )(implicit val m: Manifest[T])
    
        class TableColumnMatcher[T](implicit desired: Manifest[T]){
            def unapply(tc: TableColumn[_]): Option[TableColumn[T]] = {
                if(tc.m == desired) Some(tc.asInstanceOf[TableColumn[T]])
                else None
            }
        }
        object TableColumnMatcher{
            lazy val IntTC = new TableColumnMatcher[Int]
            lazy val DoubleTC = new TableColumnMatcher[Double]
        }
    
    
        class Analysis(data: IndexedSeq[TableColumn[_]]){
            import TableColumnMatcher._
            val transformedData = data.map{_ match{
                case IntTC(tc) => println("Column of Ints!"); 
                case DoubleTC(tc) => println("Column of Doubles!")
                case _ => println("no match")
            }}
        }
    
        new Analysis(IndexedSeq(
                new TableColumn(IndexedSeq(1,2,3)),
                new TableColumn(IndexedSeq(1.0,2.0,3.0))
        ))
    }
    

相关问题