2

想象一个抽象类 A,它有一组案例类。我们不知道有多少集合类,甚至不知道这些案例类的名称。

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")
}

我想通过参数将案例类类型传递给方法。我想要这个的原因是因为我将在一个文件中配置一组规则。我想加载这些规则并使用模式匹配这些规则提供的一些信息。我想做这样的事情:

def printer (a: A, B: A) = {
   a match{
       case B(f) => println("f")
   }
}

这可能吗?

如果不是那么容易,我可以在模式匹配中使用抽象类吗?如果我可以简单地使用抽象类,那将是完美的,因为它具有所有案例类的主要结构。

编辑:

忘了提到案例类可以有不同的参数,所以最好使用基于类 A 的东西(因为我只能用字段进行模式匹配)

4

3 回答 3

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
于 2012-04-15T19:09:33.187 回答
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:添加了可变数量和类型的参数的用法。

于 2012-04-15T19:45:25.597 回答
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)
   }
}
于 2012-04-15T23:47:10.923 回答