加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 为什么结构化类型的编译时生成技术会阻止单独编译?

发布时间:2020-12-16 10:07:16 所属栏目:安全 来源:网络整理
导读:我正在阅读(好吧,略读)Dubochet和Odersky的 Compiling Structural Types on the JVM,并对以下声明感到困惑: Generative techniques create Java interfaces to stand in for structural types on the JVM. The complexity of such techniques lies in that
我正在阅读(好吧,略读)Dubochet和Odersky的 Compiling Structural Types on the JVM,并对以下声明感到困惑:

Generative techniques create Java interfaces to stand in
for structural types on the JVM. The complexity of such
techniques lies in that all classes that are to be used as
structural types anywhere in the program must implement
the right interfaces. When this is done at compile time,it
prevents separate compilation.

(重点补充)

考虑论文中的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.

在任何情况下,您可能不希望每次使用结构类型时手动编码类型类.如果你真的希望编译器自动创建一个界面并为你做一些魔术,它可能会变得混乱.每次定义结构类型时,编译器都必须为它创建一个接口(也许在以太的某个地方?).我们现在需要为这些东西添加名称空间.此外,每次调用时,编译器都必须生成某种类型的包装器实现类(同样具有命名空间问题).最后,如果我们有两种不同的方法,它们具有相同的结构类型,我们只是分解了我们需要的接口数量.

并不是说障碍无法克服,但如果你想对特定类型进行“直接”访问的结构类型,那么类型 – 特征模式似乎是你今天最好的选择.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读