我正在尝试在Scala中做一些我不确定的事情。我很喜欢社区的一些反馈。
说我对某些'东西'有一个密封的特性,它的一些具体扩展,以及一个与该特征的某些实现一起工作的泛型类。
sealed trait Thing
class CoolThing extends Thing
class OtherThing extends Thing
class BoxOfThings[T <: Thing]
现在,我可以定义另一个处理两个“盒子”的类,如此......
class PairOfBoxes(boxOne: BoxOfThings[_ <: Thing], boxTwo: BoxOfThings[_ <: Thing])
但是,在这里创建PairOfBoxes
并使用一个CoolThing
s和另一个OtherThing
s完全没问题。我想声明boxOne
和boxTwo
包含相同类型的Thing
..是否尽可能?
例如:
// Cool things..
val boxOfCoolThings = new BoxOfThings[CoolThing]
val anotherBoxOfCoolThings = new BoxOfThings[CoolThing]
// Other things..
val boxOfOtherThings = new BoxOfThings[OtherThing]
// A pair of cool boxes, no problem:
new PairOfBoxes(boxOfCoolThings, anotherBoxOfCoolThings)
// A pair of different boxes, compiles but I don't want it to:
new PairOfBoxes(boxOfOtherThings, anotherBoxOfCoolThings)
我可以通过制作PairOfBoxes
通用本身来做到这一点,就像这样......
class TypedPairOfBoxes[T <: BoxOfThings[_ <: Thing]](boxOne: T, boxTwo: T)
它有效,但它很丑..
// A pair of cool boxes, no problem:
new TypedPairOfBoxes[BoxOfThings[CoolThing]](boxOfCoolThings, anotherBoxOfCoolThings)
// A pair of different boxes, doesn't compile:
val mixedPair = new TypedPairOfBoxes[BoxOfThings[CoolThing]](boxOfOtherThings, anotherBoxOfCoolThings)
我想避免这是我可以。它将问题推向上游并迫使我们指定每个TypedPairOfBoxes
的内容。简单地使用无类型的PairOfBoxes
是理想的,它声明它的参数属于同一类型。
可能的?
谢谢!
答案 0 :(得分:1)
你只需要写为:
class TypedPairOfBoxes[T <: Thing](one: BoxOfThings[T], two: BoxOfThings[T])
然后:
scala> new TypedPairOfBoxes(boxOfOtherThings, anotherBoxOfCoolThings)
<console>:15: error: type mismatch;
found : BoxOfThings[OtherThing]
required: BoxOfThings[Thing]
Note: OtherThing <: Thing, but class BoxOfThings is invariant in type T.
You may wish to define T as +T instead. (SLS 4.5)
new TypedPairOfBoxes(boxOfOtherThings, anotherBoxOfCoolThings)
^
<console>:15: error: type mismatch;
found : BoxOfThings[CoolThing]
required: BoxOfThings[Thing]
Note: CoolThing <: Thing, but class BoxOfThings is invariant in type T.
You may wish to define T as +T instead. (SLS 4.5)
new TypedPairOfBoxes(boxOfOtherThings, anotherBoxOfCoolThings)
^
scala> new TypedPairOfBoxes(boxOfCoolThings, anotherBoxOfCoolThings)
res3: TypedPairOfBoxes[CoolThing] = TypedPairOfBoxes@2f5e1167
答案 1 :(得分:0)
我&lt; 3 Scala
Scala可以推断出泛型类型,这样我就可以定义一个“丑陋”的类型,但在使用它时不需要指定具体的实现。
通过这种实现,我能够定义类似于上面问题中的类型的类型。
class TypedPairOfBoxes[T, BoxOfThings[T <: Thing]](boxOne: BoxOfThings[T], boxTwo: BoxOfThings[T])
..它看起来有点粗糙,但可以像这样使用:
// Both boxes contain cool things, no problem:
new TypedPairOfBoxes(boxOfCoolThings, anotherBoxOfCoolThing)
// These boxes contain different things, doesn't compile:
new TypedPairOfBoxes(boxOfOtherThings, anotherBoxOfCoolThing)
惊人的。
修改强>
正如@Eastsun所证明的那样,通用定义的后半部分未被使用。所以可以写成:
class TypedPairOfBoxes[T <: Thing](boxOne: BoxOfThings[T], boxTwo: BoxOfThings[T])
这看起来非常像Java。但令人惊奇的是,Scala从参数中推断出泛型类型。