Scala类型推理系统有其局限性。
例如,在以下类中。我希望有一个工厂FooFactory
创建Foo
和FooChanger
的实例,可以修改FooFactory
创建的实例。
我在工厂创建Foo
和FooChanger
之后,我想在FooFactory
对象创建的对象中使用更换器,但是,scala不是能够识别myOwnChanger.fooFactory.Foo
和factory.Foo
类型是相同的。
一种可能的解决方案是在所有客户端代码中强制转换或仅使用factory.theFooChanger.fooFactory
。两者都是丑陋的解决方案,迫使客户做一些不自然的事情。
问题是:可以采取哪些措施来避免客户端出现问题?有没有办法告诉推理器,其余代码myOwnChanger.fooFactory.Foo
和factory.Foo
是否相同?
class FooChangerFactory(val fooFactory: FooFactory) {
class FooChanger
def change(foo: fooFactory.Foo) = foo
}
class FooFactory(i: Int) {
class Foo private[FooFactory] ()
def create = new Foo
def theFooChanger = new FooChangerFactory(this)
}
val factory = new FooFactory(1)
val myFoo = factory.create
val myOwnChanger = factory.theFooChanger
myOwnChanger.change(myFoo) // error here! it expects myOwnChanger.fooFactory.Foo
答案 0 :(得分:3)
替换
def change(foo: fooFactory.Foo) = foo
带
def change(foo: FooFactory#Foo) = foo
问题的存在是因为,在Scala中,内部类型是路径依赖的(即对于每个FooFactory
实例,其内部类型Foo
对于该实例是“唯一的” )。 #
的使用称为type projection 。考虑这一点的方法是FooFactory#Foo
是Foo
所有实例中所有路径依赖FooFactory
的常见超类型。