简体   繁体   English

Scala 编译错误:未找到:类型_$1

[英]Scala compilation error: not found: type _$1

I am researching about existential types in Scala 2.12.x .我正在研究 Scala 2.12.x中的存在类型。 For that I'm testing the following code:为此,我正在测试以下代码:

trait Parent
class ChildA extends Parent
class ChildB extends Parent

def whatIsInside(opt: Option[_ <: Parent]): String = {
  opt match {
    case _: Option[_ <: ChildA] => "ChildA"
    case _: Option[_ <: ChildB] => "ChildB"
    case _                      => throw new IllegalArgumentException("unknown type")
  }
}


whatIsInside(Some(new ChildA))

I don't expect this to work at runtime because of type erasure, but nevertheless this does not even compile.由于类型擦除,我不希望它在运行时工作,但是这甚至不能编译。 I am getting the following error:我收到以下错误:

[error] ExistentialTypes.scala:12:24: not found: type _$2
[error]         case _: Option[_ <: ChildA] => "ChildA"
[error]                        ^
[error] ExistentialTypes.scala:13:24: not found: type _$3
[error]         case _: Option[_ <: ChildB] => "ChildB"
[error]                        ^

Can someone explain these errors?有人可以解释这些错误吗?

(Not a full answer, but a few notes and links; Maybe it can serve as a starting point for someone else) (不是完整的答案,而是一些注释和链接;也许它可以作为其他人的起点)

In 2.12.13, the compiler seems to be able to prove that F[_ <: X] and F[X] are the same type if X occurs in covariant position:在 2.12.13 中,如果X出现在协变 position 中,编译器似乎能够证明F[_ <: X]F[X]是同一类型:

println(implicitly[Option[_ <: ChildA] =:= Option[ChildA]])

This compiles (with warnings, but it compiles):这编译(带有警告,但它编译):

trait Parent
class ChildA extends Parent
class ChildB extends Parent

def whatIsInside(opt: Option[_ <: Parent]): String = {
  opt match {
    case _: Option[ChildA] => "ChildA"
    case _: Option[ChildB] => "ChildB"
    case None            => "None"
    case _ => throw new Error("meh")
  }
}

This does not compile:这不会编译:

trait Parent
class ChildA extends Parent
class ChildB extends Parent

def whatIsInside(opt: Option[_ <: Parent]): String = {
  opt match {
    case _: Option[_ <: ChildA] => "ChildA"
    case _: Option[_ <: ChildB] => "ChildB"
    case None            => "None"
    case _ => throw new Error("meh")
  }
}

So, it seems that it must have something to do with the bounds inference for the synthetic _$2 type-variable.因此,它似乎必须与合成_$2类型变量的边界推断有关。

Also, this compiles:此外,这编译:

def testConforms[A >: Nothing <: ChildA](ca: Option[A]): Option[_ <: Parent] = ca

so, unless I'm misinterpreting the spec :所以,除非我误解了规范

If there exists a substitution σ over the type variables a_i,…,a_n such that σT conforms to pt , one determines the weakest subtype constraints C1 over the type variables a1,…,an such that C0 ∧ C1 implies that T conforms to [the expected type] pt .如果在类型变量a_i,…,a_n上存在替换σ ,使得σT符合pt ,则确定类型变量a1,…,an上的最弱子类型约束C1 ,使得C0 ∧ C1意味着T符合 [the预期类型] pt

, the pt would be Option[_ <: Parent] , then a1,...,an would be the single synthetic type _$2 , and the constraints _$2 >: Nothing <: ChildA should make the type Option[_$2] conform to Option[_ <: Parent] . , pt将是Option[_ <: Parent] ,然后a1,...,an将是单个合成类型_$2 ,并且约束_$2 >: Nothing <: ChildA应该使类型Option[_$2]符合Option[_ <: Parent] So, it seems that it should work, but doesn't.所以,它似乎应该工作,但没有。


Bonus奖金

If you just wanted to make it work, then just skip all those wildcards, they aren't needed:如果您只是想让它工作,那么只需跳过所有这些通配符,它们不是必需的:

trait Parent
class ChildA extends Parent
class ChildB extends Parent

def whatIsInside(opt: Option[Parent]): String = {
  opt match {
    case Some(_: ChildA) => "ChildA"
    case Some(_: ChildB) => "ChildB"
    case None            => "None"
    case _ => throw new Error("meh")
  }
}


whatIsInside(Some(new ChildA))
whatIsInside(Some(new ChildB))
whatIsInside(None)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM