微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

这不能像预期的那样工作(因为我试图从外部服务器调用一个私人运行包):

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编译器将生成一个公共方法,并在内部处理此可见性.

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

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

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

Scala编译器再次生成一个公共方法,并在内部管理可见性.这不是一个功能,而是编译器不检查结构类型的Scala内部可见性的错误.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐