【发布时间】:2018-10-07 04:35:21
【问题描述】:
我一直在阅读有关 Dotty 的文章,因为它看起来即将成为 scala 3,并注意到类型投影被认为是“不合理的”并从语言中删除...
这看起来很糟糕,因为我已经看到了几个真正有用的用例。例如:
trait Contents
class Foo extends Contents
class Bar extends Contents
trait Container[T <: Contents] { type ContentType = T }
class FooContainer extends Container[Foo]
class BarContainer extends Container[Bar]
trait Manager[T <: Container[_]] {
type ContainerType = T
type ContentType = T#ContentType
def getContents: ContentType
def createContainer(contents: ContentType): ContainerType
}
如何在 Dotty 中做这样的事情?向Manager添加第二个类型参数?但是,除了使创建和操作Manager 的实例变得非常乏味之外,它也不太有效,因为没有办法强制这两种类型之间的关系(Manager[FooContainer, Bar] 不应该合法)。
然后,还有其他用途,如类型 lambdas 和部分应用类型,它们对于创建偏向函子等很有用......或者这些(部分应用类型)是否成为 Dotty 中的“一等公民”?
编辑
为了回答 cmets 中的问题,这里有一个他可以使用的有点做作的例子。假设,我的Managers实际上是阿卡Actors:
abstract class BaseManager[T <: Container[_]](
val storage: ContentStorage[T#ContentType]
) extends Actor with Manager[T] {
def withContents(container: T, content: ContentType): ContainerType
def withoutContents: T
var container: T = withoutContents
def receive: Receive {
case ContentsChanged =>
container = withContents(container, storage.get)
case ContainerRequester =>
sender ! container
// ... other common actions
}
}
class FooManager(storage: FooStorage) extends BaseManager[FooContainer](storage) {
def withContents(container: FooContainer, content: Foo) =
container.copy(Some(content))
def withoutContent = FooContainer(None)
override def receive: Receive = super.receive orElse {
// some additional actions, specific to Foo
}
}
case class FooContainer(content: Option[Foo]) extends Container[Foo]{
// some extremely expensive calculations that happen when
// content is assigned, so that we can cache the result in container
}
【问题讨论】:
-
您能举例说明如何使用 Manager 吗?这样可以更轻松地提出替代设计。
-
@GuillaumeMartres 我在问题中添加了一个示例
-
您的示例中缺少某些内容,BaseManager 构造函数采用参数
storage但FooManager扩展BaseManager没有参数。 -
@GuillaumeMartres 抱歉,已修复...
-
@Dima
Foo-BarMCVE 中的代码无法编译。Container具有泛型,而在Manager[T <: Container]中使用时没有泛型。ContainerType在Manager中定义了两次。
标签: scala scala-3 dotty type-projection match-types