gpt4 book ai didi

scala - 什么时候发生类型删除?

转载 作者:行者123 更新时间:2023-12-02 00:24:20 25 4
gpt4 key购买 nike

scala 的语法很有前途。我原以为 scala 不仅仅是舒适的 java 并且可以引入全新的编程范式,但是语法允许的许多功能在语义上是不正确的。因此,我开始寻找 Scala 的局限性并寻找消除这些局限性的技巧。尽管我只是编写一个测试项目来从其他角度适应 Scala 方式和模式。

主要障碍是从 jvm 实现继承的类型删除。我可以写一篇小文,名字叫《被类型删除毁掉的十种美丽模式》。据说类型删除会污染泛型,但我偶然发现了 mixins 中的类型删除。我认为这是在 scala 中实现 mixin 的问题。

序言

trait T1
trait T2

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

使用 mixins 破坏代码

trait B2 extends B1 {
def typeMe(x:T1 with T2) {}
}

将 mixin 声明为单独特征的工作代码

trait T3 extends T1 with T2
trait B3 extends B1 {
def typeMe(x:T3) {}
}

错误是:

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)

可用的最佳解决方法是什么?引入新特征是冗长的(尤其是对于大型混合链)并导致类型不兼容。添加模拟隐式参数也不是 Elixir ,因为它会增加开销。


更新:

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

最佳答案

您尝试执行的操作存在一些问题。

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

其次,您的“工作”代码实际上并不像您认为的那样工作。这需要对子类型化、协变和逆变有一点了解。 (Foo <: Bar 表示“Foo 是 Bar 的子类型”,或者非正式地表示“Foo 比 Bar 更具体”)。函数的输入是逆变的,输出是协变的,这意味着函数 A => B <: W => V仅当W <: AB <: V .

现在考虑你的函数:

B1.typeMe(x:T1)
B3.typeMe(x:T3)

B3.typeMe 的输入是T3 , 而输入类型为 B1.typeMeT1 .然而,T3 <: T1 (T3 比 T1 更具体),因此 B3.typeMe 的类型不能B1.typeMe 类型的子类型.相反,它们被简单地视为独立的功能,有时会出现一些令人毛骨悚然的无声阴影。老实说,这可能会发出错误或至少发出警告。值得庆幸的是,另一个版本可以。

关于scala - 什么时候发生类型删除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9472031/

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