首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >类型擦除是什么时候发生的?

类型擦除是什么时候发生的?
EN

Stack Overflow用户
提问于 2012-02-27 20:47:03
回答 1查看 270关注 0票数 3

scala的语法非常有前途。我原以为scala不仅仅是简单的java,可以引入全新的编程范式,但是语法允许的许多特性在语义上是不正确的。因此,我开始寻找scala的限制和黑客来消除它们。虽然我只是编写一个测试项目以适应scala的方式和模式,但从其他角度来看。

主要的障碍是从jvm实现继承的类型擦除。我可以写一篇小文章,题为“擦除类型毁掉的十种美丽图案”。据说,类型擦除会污染仿制药,但我无意中发现了混药中的类型擦除。我认为scala中的mixin实现存在问题。

前言

代码语言:javascript
复制
trait T1
trait T2

trait B1 {
  def typeMe(x:T1){}
}

混合码破译

代码语言:javascript
复制
trait B2 extends B1 {
  def typeMe(x:T1 with T2) {}
}

将混合蛋白声明为独立特性的工作代码

代码语言:javascript
复制
trait T3 extends T1 with T2
trait B3 extends B1 {
  def typeMe(x:T3) {}
}

错误是:

代码语言:javascript
复制
error: name clash between defined and inherited member:
method typeMe:(x: T1 with T2)Unit and
method typeMe:(x: T1)Unit in trait B1
have same type after erasure: (x: $line12.$read#$iw#$iw#T1)Unit
    def typeMe(x:T1 with T2)

最好的解决办法是什么?引入新的特性是冗长的(特别是对于大的混合链),并导致类型不兼容。添加模拟隐式参数也不是灵丹妙药,因为它增加了开销。

最新情况:

很抱歉,我问错问题了。我更感兴趣的是所描述的错误的性质,而不是它的解决办法。类型擦除在哪里发生?在被认为是类型擦除源的代码中,我看不到泛型。编译器行为背后的机制是什么?

EN

回答 1

Stack Overflow用户

发布于 2012-02-28 02:41:55

你想做的事情有几个问题。

首先,类型擦除发生的时间并不重要。这是因为类型擦除的概念是,无论您在计算之前还是之后删除类型,结果都应该是相同的。对于JVM语言,在编译时iinm会发生一些擦除。

其次,您的“工作”代码实际上并不像您认为的那样工作。这需要对子类型、协方差和对比方差有一点了解。(Foo <: Bar的意思是"Foo是Bar的一个子类型“,或者非正式地说,"Foo比Bar更具体”)。函数在它们的输入中是反变的,在它们的输出中是协变的,这意味着函数A => B <: W => V只在W <: AB <: V的情况下。

现在考虑一下您的功能:

代码语言:javascript
复制
B1.typeMe(x:T1)
B3.typeMe(x:T3)

B3.typeMe的输入是T3,而B1.typeMe的输入类型是T1。但是,T3 <: T1 (T3比T1)更具体,因此B3.typeMe的类型不能是B1.typeMe类型的子类型。相反,它们只是被认为是单独的功能,有时会发生一些令人毛骨悚然的沉默。老实说,这可能会发出一个错误或至少一个警告。谢天谢地,另一个版本做到了。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9472031

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档