想象一个抽象的A类,它有一组case类。我们不知道有多少集合类,甚至不知道这些案例类的名称。
abstract class A(field: String)
//Example of a case class that extends A
case class B(f: String) extends A(f)
现在我有了这个:
a match {
case B(f) => println("f")
}
我想通过参数将case类类型传递给方法。我想要这个的原因是因为我将在文件中配置一组规则。我想加载这些规则并使用模式匹配与这些规则提供的一些信息。我想做这样的事情:
def printer (a: A, B: A) = {
a match{
case B(f) => println("f")
}
}
这可能吗?
如果不是那么容易,我可以在模式匹配中使用抽象类吗?如果我可以简单地使用抽象类,那将是完美的,因为它具有所有案例类的主要结构。
编辑:
忘记提到案例类可以有不同的参数,所以最好使用基于类A的东西(因为我可以只使用字段匹配模式)
答案 0 :(得分:5)
不像你试过的那样。但是如果你使用 Manifest 作为上下文绑定,你可以使它工作:
scala> trait Foo
defined trait Foo
scala> case class Bar(baz: String) extends Foo
defined class Bar
scala> def boo[A <: Foo : Manifest](foo: Foo) =
| if (foo.getClass isAssignableFrom manifest[A].erasure) "foo" else "boo"
boo: [A <: Foo](foo: Foo)(implicit evidence$1: Manifest[A])java.lang.String
scala> boo[Foo](Bar(""))
res0: java.lang.String = boo
scala> boo[Bar](Bar(""))
res1: java.lang.String = foo
答案 1 :(得分:1)
您可以从案例类的随播对象中提取unapply
方法并使用它:
scala> :paste
// Entering paste mode (ctrl-D to finish)
abstract class A(field: String)
case class B(f: String) extends A(f)
case class C(f: String) extends A(f)
case class E(f: String, f1: Int) extends A(f)
case class F(f: String, f1: Int) extends A(f)
class Unapplyer[T: Manifest, R](f: T => Option[R]) {
def unapply(a: Any): Option[R] = {
if (manifest[T].erasure.isInstance(a)) f(a.asInstanceOf[T]) else None
}
}
def printer[T: Manifest, R](a: A, b: T => Option[R]) {
val P = new Unapplyer(b)
a match {
case P((f, f1)) => println(f + " - " + f1)
case P(f) => println(f)
case _ => println("oops")
}
}
// Exiting paste mode, now interpreting.
defined class A
defined class B
defined class C
defined class E
defined class F
defined class Unapplyer
printer: [T, R](a: A, b: (T) => Option[R])(implicit evidence$2: Manifest[T])Unit
scala> printer(B("test"), B.unapply _ )
test
scala> printer(B("test"), C.unapply _ )
oops
scala> printer(E("test", 1), E.unapply _ )
test - 1
scala> printer(E("test", 1), F.unapply _ )
oops
scala> printer(E("test", 1), B.unapply _ )
oops
UPD:使用变量编号和参数类型添加了用法。
答案 2 :(得分:0)
我不明白为什么要将类型传递给方法。使用模式匹配时,无论如何都要检查类型。那么为什么要传递呢? 你可以写
abstract class A(field: String)
case class B(f: String) extends A(f)
case class C(i: Int) extends A(i.toString)
def printer (a: A) = {
a match{
case B(f) => println(f)
case C(i) => println(i)
}
}