我在浏览Scalameta's code named Trees.scala时,偶然发现了这段我很难理解的代码。
@branch trait Name extends Ref { def value: String }
object Name {
def apply(value: String): Name = if (value == "") Name.Anonymous() else Name.Indeterminate(value)
def unapply(name: Name): Option[String] = Some(name.value)
@ast class Anonymous() extends Name {
def value = ""
checkParent(ParentChecks.NameAnonymous)
}
@ast class Indeterminate(value: Predef.String @nonEmpty) extends Name
}在这里,Metals指出
value Indeterminate is not a member of scala.Meta.Name
value Anonymous is not a member of scala.Meta.Name因此,它抱怨apply不能引用内部类。尽管如此,源代码实际上还是成功编译了。然而,下面的代码不是这样的,上面的代码基本上归结为:
trait Hihi { }
object Hihi {
def apply(value: String): Hihi = if (value == "") Hihi.Class1() else Hihi.Class2()
@ast class Class1() extends Hihi {
def value = ""
}
@ast class Class2() extends Hihi
}scalac编译器指出Class1和Class2不是Hihi的成员。那么,为什么Scalameta的代码会编译,而另一个更简单的代码却会失败呢?
发布于 2021-06-09 19:22:30
这对我来说很有效,没有注释(在Scala2中,因此Bar和Baz是case classes):
trait Foo { }
object Foo {
def apply(v: String): Foo = if (v.isEmpty) Foo.Bar() else Foo.Baz(v)
case class Bar() extends Foo { def value = "" }
case class Baz(value: String) extends Foo
}我怀疑如果您的作用域中没有ast注释,@ast class Class1将无法编译,从而导致Class1不是成员。
https://stackoverflow.com/questions/67899120
复制相似问题