gpt4 book ai didi

scala - 密封类的 list 实例上的模式匹配

转载 作者:行者123 更新时间:2023-12-03 18:33:41 25 4
gpt4 key购买 nike

给定的类(class)

sealed abstract class A

case class B(param: String) extends A

case class C(param: Int) extends A

trait Z {}

class Z1 extends Z {}

class Z2 extends Z {}

def zFor[T <: A : Manifest]: Option[Z] = {
val z = manifest[T].erasure
if (z == classOf[B]) {
Some(new Z1)
} else
if (z == classOf[C]) {
Some(new Z2)
} else {
None
}
}

我认为这里模式匹配的问题是不可能在字节码中构建模式匹配表。这个问题有什么解决方法吗?我可以使用编译器在 Manifest 中生成的一些 Int 吗?

最佳答案

如果您有一个更复杂的类层次结构,那么您编写它的方式就不是很健壮,因为如果您有一个类 D <: C ,然后 classOf[D] != classOf[C] .所以你无论如何都不想进行模式匹配。但你可以;你不能打电话classOf[X]在模式匹配的中间,但你可以

def zFor[T <: A : Manifest]: Option[Z] = {
val ClassB = classOf[B]
val ClassC = classOf[C]
manifest[T].erasure match {
case ClassB => Some(new Z1)
case ClassC => Some(new Z2)
case _ => None
}
}

只要您确定您处于只需要检测类层次结构的叶子的情况。 (您可能应该通过标记 BC final 来确定。)

或者,您可以使用 isAssignableFrom执行运行时测试:
def zFor2[T <: A : Manifest]: Option[Z] = {
manifest[T].erasure match {
case x if classOf[B].isAssignableFrom(x) => Some(new Z1)
case x if classOf[C].isAssignableFrom(x) => Some(new Z2)
case _ => None
}
}

现在
class D extends C(5) {}

scala> zFor[D]
res5: Option[Z] = None

scala> zFor2[D]
res6: Option[Z] = Some(Z2@2556af33)

关于scala - 密封类的 list 实例上的模式匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16629967/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com