This great daily Scala article opisuje, w jaki sposób przezwyciężyć wymazywanie typu w dopasowaniu. Próbuję zastosować tę technikę do transformacji IndexesSeq sparametryzowanych typów, ale dopasowania się nie udają. Dlaczego tak jest i jak mogę to naprawić?Dopasowanie wzorca Scala z manifestem
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))
))
}
Gdybym odkomentuj linię Def potem widzę linie takie jak
prototype.Example$TableColumn[_ <: Any], prototype.Example$TableColumn[Int]
sugeruje, że _ w konstruktorze analizy jest problem, ale nie wiem, co jeszcze umieścić w tam.
Czytałaś w artykule tę frazę: „Bardzo ważne jest, aby zauważyć wykorzystanie typeArguments manifestu. To zwraca listę manifestów każdego typuArgument.Nie można po prostu porównać pożądanego == m, ponieważ oczywiste porównania nie są głębokie.Nie ma słabości w tym kodzie, że obsługuje tylko generics, które są 1 poziom głębokości. "? Okoliczna dyskusja nie powie Ci dokładnie, jak to naprawić, ale powinna Ci powiedzieć, dlaczego to nie działa. –
@Rex: Zagubiłem się w kilku drobniejszych punktach artykułu, ale teraz zwracasz na to uwagę, widzę problem i zastanawiam się, czy mogę go rozwiązać w jakiś inny sposób. Dzięki – Pengin
Istnieją dwa problemy: jeden to zagnieżdżanie, a drugi to to, że masz wiele typów na jednej liście, co wymaga poszerzenia typu. Myślę, że w ostatecznym rozwiązaniu będziesz chciał mieć 'isAssignableFrom', ale niestety nie mam teraz czasu, aby napisać rozwiązanie samemu. –