scala – 为什么结构化类型的编译时生成技术会阻止单独编译?
我正在阅读(好吧,略读)Dubochet和Odersky的
Compiling Structural Types on the JVM,并对以下声明感到困惑:
(重点补充) 考虑论文中的autoclose示例: type Closeable = Any { def close(): Unit } def autoclose(t: Closeable)(run: Closeable => Unit): Unit = { try { run(t) } finally { t.close } } 我们无法为Closeable类型生成一个接口,如下所示: public interface AnonymousInterface1 { public void close(); } 并将我们对autoclose的定义转换为 // UPDATE: using a view bound here,so implicit conversion is applied on-demand def autoclose[T <% AnonymousInterface1](t: T)(run: T => Unit): Unit = { try { run(t) } finally { t.close } } 然后考虑autoclose的呼叫站点: val fis = new FileInputStream(new File("f.txt")) autoclose(fis) { ... } 由于fis是FileInputStream,它没有实现AnonymousInterface1,我们需要生成一个包装器: class FileInputStreamAnonymousInterface1Proxy(val self: FileInputStream) extends AnonymousInterface1 { def close() = self.close(); } object FileInputStreamAnonymousInterface1Proxy { implicit def fis2proxy(fis: FileInputStream): FileInputStreamAnonymousInterface1Proxy = new FileInputStreamAnonymousInterface1Proxy(fis) } 我必须遗漏一些东西,但我不清楚它是什么.为什么这种方法会阻止单独编译? 解决方法
我实际上使用了你在
Scala ARM library中描述的隐式方法(使用类型类).请记住,这是一个手工编码的问题解决方案.
这里最大的问题是隐式解决方案.编译器不会为您动态生成包装器,您必须提前生成包装器并确保它们是隐式范围.这意味着(对于Scala-ARM)我们为任何资源提供“通用”包装器,并在找不到合适的包装器时回退到基于反射的类型.这提供了允许用户使用常规隐式规则指定自己的包装器的优点. 请参阅:The Resource Type-trait及其所有预定义的包装器. 此外,我在博客中详细介绍了这种隐含分辨率魔法的技术:Monkey Patching,Duck Typing and Type Classes. 在任何情况下,您可能不希望每次使用结构类型时手动编码类型类.如果你真的希望编译器自动创建一个界面并为你做一些魔术,它可能会变得混乱.每次定义结构类型时,编译器都必须为它创建一个接口(也许在以太的某个地方?).我们现在需要为这些东西添加名称空间.此外,每次调用时,编译器都必须生成某种类型的包装器实现类(同样具有命名空间问题).最后,如果我们有两种不同的方法,它们具有相同的结构类型,我们只是分解了我们需要的接口数量. 并不是说障碍无法克服,但如果你想对特定类型进行“直接”访问的结构类型,那么类型 – 特征模式似乎是你今天最好的选择. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |