【问题标题】:Pattern matching with generics与泛型匹配的模式
【发布时间】:2011-09-22 01:08:15
【问题描述】:

给定以下类模式匹配:

clazz match {
  case MyClass => someMethod[MyClass]
}

是否可以根据模式匹配提出的通用方式引用 MyClass?例如,如果我有多个 MyClass 的子类,是否可以编写一个简单的模式匹配来将匹配的类型传递给someMethod

clazz match {
  case m <: MyClass => someMethod[m]
}

【问题讨论】:

  • 它闻起来像Manifest,但由于只让我们完成一个不可能的答案而不为其他选项留出空间,我不得不对“我可以写一个简单的模式匹配来通过匹配类型”。

标签: scala


【解决方案1】:

不幸的是,类型在 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
}

但我仍然无法让隐式发挥作用:

test[String]
test[PayLoad]  // ouch, not doin it
test[PayLoad](new Carry[PayLoad])  // sucks

因此,如果您想避免严重的脑损伤,我会忘记该项目或寻找另一种语言。也许 Haskell 在这里更好?我仍然希望我们最终能够匹配类型,但我的希望很低。

也许 scalaz 的人想出了一个解决方案,他们几乎将 Scala 的类型系统发挥到了极限。

【讨论】:

  • 嗯。我认为从这个例子来看,“忘记[ting]该项目或寻找[ing]另一种语言”有点极端^^
  • 嗯,这反映了我对尝试实现类似目标的挫败感。花了我几个星期的永久重构,但没有找到可行的解决方案。所以我在这里建议不要重复这种经历和安全一个月的工作。
  • 您的代码无法运行,因为canCarry 需要一个非隐式参数,因此难怪它从未应用过。但是,存在一个解决方案:我建议您将MaybeCarry 替换为OptManifest,将NoCarry 替换为NoManifest,将Carry 替换为Manifest/Manifest/ClassManifest(我看到两者之间的区别主要在于实现equals)。
【解决方案2】:

您的代码不是很清楚,因为至少在 java 中clazzjava.lang.Class 类型变量和变体的典型名称。我仍然相信clazz 不是Class 的实例,而是你自己的类。

在 Java 和 Scala 中,给定一个对象 o: AnyRef,您可以在运行时通过 o.getClass: Class[_] 访问其类,例如通过反射 API 创建该类的实例。但是,类型参数是在编译时传递的,因此您不能在编译时按原样传递类型。要么在整个地方使用AnyRef 作为类型(我认为这会起作用),要么如果你有更高级的需求,你可以使用反射 API。

【讨论】:

    猜你喜欢
    • 2011-10-25
    • 1970-01-01
    • 2019-08-04
    • 1970-01-01
    • 2016-10-29
    • 1970-01-01
    • 1970-01-01
    • 2018-06-20
    相关资源
    最近更新 更多