在某些情况下,我想使用内部类型作为泛型类型的替代品,例如在以下情况下Dependent[T <: BaseType]
,我没有定义 ,而是这样定义它:
abstract class BaseType {
type N
def create(v: Int): N
class Dependent(val n: N) {
def +(other: Dependent) = new Dependent(create(n.hashCode() + n.hashCode()))
}
}
object BaseType {
class Aggregator[T <: BaseType](val seq: Seq[T#Dependent]) {
def result() = seq.reduce(_ + _)
}
}
显然这不会编译,因为Dependent
现在是一个 Inner 类,并且Dependent
在不同的 BaseType 实例下创建的不同,彼此不能互操作。(BTW 会抛出以下编译错误)
Error:(15, 35) type mismatch;
found : T#Inner
required: _33.Inner where val _33: T
def result() = seq.reduce(_ + _)
然而这个问题在scala中应该有一个简单的解决方案,因为在java中这样的任务可以通过以下方式轻松完成:
static class Dependent { ...
在 Scala 中拥有比 java 更长的代码是没有意义的。scala 中的一个直接类比是在 BaseType 中添加一个强制规则,这要求其所有实现都是对象/单例而不是类。但是我还没有看到这样的功能。
所以问题是,在java中可以轻松完成的相同事情的最短方法是什么?
UPDATE显然我不太清楚我的意图,我想要的不是Dependent
按原样使用类,而是扩展 BaseTypeBaseType
作为 的类型参数Dependent
,例如,如果我定义了 2 个对象:
object Sub1 extends BaseType {
override type N = Long
override def create(v: Int): N = v.toLong
}
object Sub2 extends BaseType {
override type N = Double
override def create(v: Int): N = v.toDouble
}
然后+
,Aggregator
如果它们来自同一个对象,则两者都可以用于 2 Dependent,这意味着这将成功:
assert(
new Aggregator(
Seq(
new Sub1.Dependent(1),
new Sub1.Dependent(2)
)).result() == new Sub1.Dependent(1) +
new Sub1.Dependent(2)
)
但这会失败:
assert(
new Aggregator(
Seq(
new Sub1.Dependent(1),
new Sub2.Dependent(2)
)).result() == new Sub1.Dependent(1) +
new Sub2.Dependent(2)
)
因为 2 个 Dependent 实例的类型不同,但是使用最新的 scala 编译器,即使第一个编译器也会失败,因为在定义 Aggregator 时,它不知道T <: BaseType
是单例。
因为在 Java 中,可以通过以下方式轻松完成此类任务:
static class Dependent { ...
不,它没有完成任务,因为 thisDependent
不能使用N
(即使它是 的类型参数BaseType
)。你需要static class Dependent<N>
,Scala 等价物是
object BaseType {
class Dependent[N]
}
如果您还没有伴随对象,这确实比 Java 稍长,但在 Scala 设计中,它并不要求它可以用更短的代码完成 Java 可以做的任何事情(或者根本没有,真的)。
如果你想
然后 + 符号和聚合器都可以用于 2 Dependent 仅当它们来自同一个对象时,这意味着这将成功
这可以做到:
class Aggregator[T <: BaseType with Singleton](val seq: Seq[T#Dependent]) {
def result() = seq.reduce(_ + _)
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句