clazz match {
case MyClass => someMethod[MyClass]
}
是否有可能是指MyClass的基于什么模式匹配想出了一个通用的方法?举例来说,如果我有MyClass的多个子类,我可以写一个简单的模式匹配的匹配系传递到someMethod
:
clazz match {
case m <: MyClass => someMethod[m]
}
clazz match {
case MyClass => someMethod[MyClass]
}
是否有可能是指MyClass的基于什么模式匹配想出了一个通用的方法?举例来说,如果我有MyClass的多个子类,我可以写一个简单的模式匹配的匹配系传递到someMethod
:
clazz match {
case m <: MyClass => someMethod[m]
}
可惜类型是不是真的在Scala中的一等公民。这意味着例如你不能对类型进行模式匹配。由于从Java平台继承的愚蠢类型擦除导致大量信息丢失。
我不知道是否有任何改善要求,但这是我的选择中最糟糕的问题之一,所以有人应该真的想出这样的要求。
事实是,您将需要传递证据参数,最好以隐式参数的形式传递。
我能想到的最好进去的
class PayLoad
trait LowPriMaybeCarry {
implicit def no[C] = new NoCarry[C]
}
object MaybeCarry extends LowPriMaybeCarry {
implicit def canCarry[C <: PayLoad](c: C) = new Carry[C]
}
sealed trait MaybeCarry[C]
final class NoCarry[C] extends MaybeCarry[C]
final class Carry[C <: PayLoad] extends MaybeCarry[C] {
type C <: PayLoad
}
class SomeClass[C <: PayLoad]
def test[C](implicit mc: MaybeCarry[C]) : Option[SomeClass[_]] = mc match {
case c: Carry[_] => Some(new SomeClass[ c.C ])
case _ => None
}
行但我仍然不能得到implicits工作:
test[String]
test[PayLoad] // ouch, not doin it
test[PayLoad](new Carry[PayLoad]) // sucks
所以,如果你想保存自己浆液性脑损坏,我会忘记项目或寻找另一种语言。也许Haskell在这里更好?我仍然希望我们能够最终匹配类型,但我的希望非常低。
也许来自scalaz的人提出了一个解决方案,他们几乎将Scala的类型系统用于极限。
呃。我认为,“忘记项目或者寻找另一种语言”在这个例子中有点极端^^ – 2011-03-20 01:16:12
好吧,这反映了我对尝试实现类似的东西感到沮丧。花费我几个星期的永久重构,而没有达到一个可行的解决方案。所以我建议在这里不要重复这个经历和一个月的工作安全。 – 2011-03-20 02:11:51
你的代码不能工作,因为'canCarry'需要一个非隐式参数,因此难怪它永远不会被应用。 然而,存在一个解决方案:我建议你用'OptManifest'替换'MaybeCarry',用NoManifest替换'NoCarry'和用'Manifest' /'ClassManifest'替换'(我看到的区别主要在于执行'equals')。 – Blaisorblade 2011-09-21 16:22:34
你的代码是不是真的清楚,因为至少在Java clazz
是java.lang.Class
类型和变化的变量,一个典型的名称。我仍然认为clazz
不是Class
的实例,而是您自己班的实例。
在Java和Scala中,给定一个对象o:AnyRef,您可以在运行时通过o.getClass: Class[_]
访问其类,并且可以通过Reflection API创建该类的实例。但是,类型参数是在编译时传递的,因此您无法在编译时按原样传递类型。要么你使用AnyRef
作为类型(这将工作,我假设),或者如果你有更高级的需求,你使用反射API。
它闻起来像'Manifest',但只是让我们完成一个不可能的答案,而不让其他选项空间,我不得不说“我可以写一个简单的模式匹配来传递匹配的类型”。 – shellholic 2011-03-22 10:21:44