gpt4 book ai didi

Scala Case 类与别名内部类型匹配编译错误?

转载 作者:行者123 更新时间:2023-12-02 02:00:14 25 4
gpt4 key购买 nike

如何使用与别名类型匹配的案例类?当我从容器中取出 CB 等时,这会起作用。

class DoStuff[TKey](
val c : Container[TKey]#CB
)
{
type CB = Container[TKey]#CB
type C1 = Container[TKey]#C1
type C2 = Container[TKey]#C2

c match {
case C1(e1) => e1 // - not found: value e1 - not found: value C1
case C2(e2) => e2 // - not found: value e2 - not found: value C2
}
}

trait Container[TKey]
{
abstract trait CB
case class C1(val e : AnyRef) extends CB
case class C2(val e : AnyRef) extends CB
}

谢谢!

最佳答案

对...Scala 中的内部类有点繁琐。在向您展示您提供的代码的重写版本之前,让我们尝试一个简单的示例。

case class Foo(x: Int) {
case class Bar(y: String)
}

现在,考虑以下代码片段:

val x = new Foo(1)
val y = new Foo(2)

val a = new x.Bar("one")
val b = new y.Bar("two")

ab最通用的类​​型是Foo#Bar,即内部类BarFoo 类型的任何外部对象。但我们可以更具体地说,a 的类型是 x.Barb 的类型是 y.Bar - 这意味着 a 是内部类 Bar 和外部对象 x 的实例,与 b 类似.

通过调用 typeOf(a)typeOf(b),您实际上可以看到类型是不同的,其中 typeOf 是一个实用程序方法如此定义。 (它只是通过相当好的类型推断和一些 Manifest 的使用来给出其参数的类型)

def typeOf[T](x: T)(implicit m: scala.reflect.Manifest[T]) = m.toString

由于内部对象持有对其封闭对象的引用,因此您无法在不以某种方式指定其外部对象的情况下实例化内部对象。因此,您可以调用 new x.Bar("one") 但不能调用 new Foo#Bar("?") - 就像在第二种情况下您没有调用t 指定您尝试构造的新对象的内部对象是什么。

那么,让我们回到您的代码片段。当您进行模式匹配时,您实际上是在调用构造函数 - 当调用 C1(e1) 时。由于 C1Container[TKey]#C1 的别名
您尝试调用内部类的构造函数而不指定其外部对象,但由于上述原因而失败。我编写代码的方式如下:

trait Container[TKey] {
abstract trait CB
case class C1(val e : AnyRef) extends CB
case class C2(val e : AnyRef) extends CB
}

class DoStuff[TKey] (val c: Container[TKey], val element: Container[TKey]#CB) {
element match {
case c.C1(e1) => Some(e1)
case c.C2(e2) => Some(e2)
case _ => None
}
}

现在可以编译了,希望它能达到您想要的效果。但请务必小心!由于类型删除,Scala 无法保证 element 实际上是 c.CB 类型或 d.CB 类型,其中 cd 中的 CB 恰好是相同的。

考虑这个例子:

def matcher(arg: Foo#Bar) = {
arg match {
case x.Bar(n) => println("x");
case y.Bar(n) => println("y");
}
}

其中xy与以前一样。尝试运行以下命令:

matcher(a)
matcher(b)

它们都打印x!

因此我会重写代码以显式在容器中包含一个元素:

trait Container[TKey] {
abstract trait CB
case class C1(val e : AnyRef) extends CB
case class C2(val e : AnyRef) extends CB
val element: CB
}

class DoStuff[TKey](val c: Container[TKey]) {
c.element match {
case c.C1(e1) => Some(e1)
case c.C2(e2) => Some(e2)
case _ => None
}
}

希望有帮助:)

--弗拉维·西普西甘

关于Scala Case 类与别名内部类型匹配编译错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1812695/

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