这是我的问题:如果某些谓词适用,我有一个很大的对象序列,我想在这些对象上应用过程(我称之为“编译器”)。为了清楚起见,我想将谓词函数与过程分开;然而,在许多情况下,谓词可能非常复杂,并且构建了我想在后面的过程函数中重用的信息。
我定义一个编译器如下:
trait Compiler[A] {
def mtch(o: SourceObject): Option[A]
def proceed(o: SourceObject, data: A): Unit
}
以及如何调用编译器:
val compilers: Seq[Compiler[_]]
val objects: Seq[SourceObject]
for (o <- objects; c <- compilers; data <- c.mtch(o)) {
c.proceed(o, data)
}
也就是说,如果 mtch
函数返回 Some(data)
,则调用 proceed
方法,其中 data
已附。但是,我无法编译它,因为我在管理编译器时不知道数据的类型。
此外,我在某些情况下实际上不需要任何数据。在我当前的状态下,我让匹配器返回 Some(null)
,这很糟糕。
最佳答案
改用路径相关类型。替换
trait Compiler[A] {
def mtch(o: SourceObject): Option[A]
def proceed(o: SourceObject, data: A): Unit
}
与
trait Compiler {
type A
def mtch(o: SourceObject): Option[A]
def proceed(o: SourceObject, data: A): Unit
}
一切都会正常。
这里的技巧是,for-commination 中的 data
类型变成 c.A
,这是 c.proceed
所期望的类型它的第二个参数。
对于null
,让编译器不需要传递参数type A = Unit
,所以返回Some(())
是否应该继续。
关于scala - 在 Scala 中的方法之间保留类型信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18899155/