Sco*_*son 4 types scala inner-classes path-dependent-type
有时在Scala中我发现我得到与路径依赖类型相关的类型不匹配,但我可以轻易地推断出事实上类型是一致的.这是一个简单的例子:
trait Foo { trait Bar }
object Main extends App {
val foo1 = new Foo { }
val foo2 = foo1
def turkle(x: foo1.Bar) {}
turkle(new foo2.Bar {})
}
Run Code Online (Sandbox Code Playgroud)
它给出:"类型不匹配;找到:需要Main.foo2.Bar的java.lang.Object:Main.foo1.Bar".
当然现在的路径Main.foo1.Bar和Main.foo2.Bar必须一致,因为我们写的val foo2 = foo1.我们可以通过将最后一行更改为来验证这一点
turkle((new foo2.Bar {}).asInstanceOf[foo1.Bar])
Run Code Online (Sandbox Code Playgroud)
这两个编译和运行没有例外.
Scala可以自动执行这样的推理吗?如果是这样,我怎么能做到这一点?
(如果没有,是否有任何前景可以将类型系统扩展到这个方向?)
我会注意到,有时斯卡拉确实出现执行这种推理.假设我trait Foo改为object Foo:
object Foo { trait Bar }
object Main extends App {
val foo1 = Foo
val foo2 = foo1
def turkle(x: foo1.Bar) {}
turkle(new foo2.Bar {})
}
Run Code Online (Sandbox Code Playgroud)
现在一切都编好了:不知何故,Scala已经解决了两者Main.foo1.Bar并且Main.foo2.Bar真的相同Foo.Bar.
Iulian Dragos 在最近的一个问题中给出了你需要的答案.简短的版本是编译器不进行流分析,所以在你的第一个例子中它不能告诉foo1.Bar和foo2.Bar是相同的类型,因为foo1和foo2只是Foo类型.但是在第二个例子中,foo1被推断为单例类型Foo.type(Foo的子类型),因此事情按预期工作.
您可以通过将foo2声明为foo1的单例类型来使您的第一个示例工作:
val foo2:foo1.type = foo1
Run Code Online (Sandbox Code Playgroud)
请参阅Scala语言规范2.9的第3.2.1节以供参考.
| 归档时间: |
|
| 查看次数: |
332 次 |
| 最近记录: |