【发布时间】:2017-02-19 13:46:57
【问题描述】:
我正在使用 Scala 并想生成一些通用代码。我想有两个班级,一个“外部”班级和一个“内部”班级。外部类应该是通用的,并接受任何遵循一些约束的内部类。这是我想要的那种架构,在不可编译的代码中。 Outer 是泛型类型,Inner 是可以在 Outer 等中使用的类型示例。
class Outer[InType](val in: InType) {
def update: Outer[InType] = new Outer[InType](in.update)
def export: String = in.export
}
object Outer {
def init[InType]: Outer[InType] = new Outer[InType](InType.empty)
}
class Inner(val n: Int) {
def update: Inner = new Inner(n + 1)
def export: String = n.toString
}
object Inner {
def empty: Inner = new Inner(0)
}
object Main {
def main(args: Array[String]): Unit = {
val outerIn: Outer[Inner] = Outer.empty[Inner]
println(outerIn.update.export) // expected to print 1
}
}
重要的一点是,无论InType 是什么,in.update 都必须返回一个“更新的”InType 对象。我还希望伴随方法是可调用的,例如InType.empty。这样Outer[InType] 和InType 都是不可变类型,并且伴随对象中定义的方法是可调用的。
前面的代码无法编译,因为它写得像 C++ 泛型类型(我的背景)。根据我提到的约束更正此代码的最简单方法是什么?我完全错了,我应该使用其他方法吗?
【问题讨论】:
-
我不明白您使用类型参数的动机。用 Inner 替换 InType 就可以了。
-
其实我应该会问,你有没有一个具体的用途,只能通过使用类型参数才能实现?否则我的建议是不要将参数多态性与子类型混合:这会使事情变得非常快,正如您从下面的答案中看到的那样。我从 +- '98 开始就不再使用 C++ 模板(天哪,可能是 20 年!),否则我会尝试和你一起走
C++ templates to parametric polymorphism路径。 -
我不知道类型参数是否是最好的解决方案。我喜欢使用方法创建类,而不是修改对象,而是返回相同类型的对象。所以这里的代码在更新和导出方面非常简单,但我正在编写的真实代码在更新调用期间对数据执行操作,这可能非常多样化,包括统计数据的计算。折叠使用 Outer 类实例作为累加器,在折叠结束时,我可能希望内部类导出一些结果。我需要能够使用 Inner 或其他处理,因此需要 type 参数。