gpt4 book ai didi

Scala:通过包外的结构类型访问包可见方法

转载 作者:行者123 更新时间:2023-12-03 23:56:44 25 4
gpt4 key购买 nike

这不能按预期工作(因为我试图从外部 run 调用包私有(private) Services ):

object Services {
class HelloPrinter {
private[Services] def run = "Hello"
}
}

val obj = new Services.HelloPrinter

但是,令人惊讶的是,这有效:
val obj: {def run: String} = new Services.HelloPrinter
obj.run

我想说,这是编译器中的一个错误,因为由于包可见性规则,HelloPrinter 与结构类型不匹配,所以它根本不应该编译!

这是程序编译但抛出运行时异常( java.lang.NoSuchMethodException )的情况:
class HelloPrinter {
private[HelloPrinter] def run = "Hello"
}

val obj: {def run: String} = new HelloPrinter
obj.run

这是我缺少的语言功能或规则,还是 Scala 中的合法错误?

最佳答案

在 JVM 级别上,范围为周围实例/类型的可见性不存在。在这种情况下,Scala 编译器将生成一个公共(public)方法并在内部处理这种可见性。

如果您使用结构类型,编译器将反射性地访问此类型的成员。它不会检查 Scala 特定的可见性标志,而只会检查 Java 字节码中定义的可见性标志。

您没有提及您使用的是哪个版本的 Scala 编译器,但我认为这是您特定版本中的错误。尝试编译时,我得到与 Jasper-M 相同的结果。原因是编译器生成的方法实际上是以类型名称为前缀的,即HelloPrinter$$run在这种情况下。将执行以下代码:

val x: { def HelloPrinter$$run: String  } = new HelloPrinter
x.run

同样,Scala 编译器只是生成一个公共(public)方法并在内部管理可见性。编译器不检查结构类型的 Scala 内部可见性不是一个特性,而是一个错误。

关于Scala:通过包外的结构类型访问包可见方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31303411/

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