当 class 及其参数从同一特征扩展时,方法签名会发生冲突
Method signature clashes when class and its parameters extends from the same trait
抱歉标题有点模糊,很难将我的问题概括为 single-liner。希望以下代码片段能更好地解释我的意图。
让我们首先为所有 Reduceable
:
的事物引入一个特征
trait Reduceable[A] {
def reduceWith(other: A): A
}
此类 Reduceable
事物的示例可以是这样的计数器:
case class GenderCounter(male: Int, female: Int)
extends Reduceable[GenderCounter] {
override def reduceWith(other: GenderCounter): GenderCounter =
GenderCounter(male + other.male, female + other.female)
}
case class FruitCounter(apples: Int, oranges: Int)
extends Reduceable[FruitCounter] {
override def reduceWith(other: FruitCounter): FruitCounter =
FruitCounter(apples + other.apples, oranges + other.oranges)
}
GenderCounter(5, 10) reduceWith GenderCounter(4, 11)
// res: GenderCounter = GenderCounter(9,21)
一个class以上面的计数器为参数,本身也可以是一个Reduceable
case class CompoundCounter(c1: GenderCounter, c2: FruitCounter)
extends Reduceable[CompoundCounter] {
override def reduceWith(
other: CompoundCounter)
: CompoundCounter = CompoundCounter(
c1 reduceWith other.c1,
c2 reduceWith other.c2
)
}
CompoundCounter(GenderCounter(5, 10), FruitCounter(11, 2)) reduceWith CompoundCounter(GenderCounter(5, 10), FruitCounter(11, 2))
// res: CompoundCounter = CompoundCounter(GenderCounter(10,20),FruitCounter(22,4))
但是,当我尝试引入一个泛型 Reduceable
class 时,问题出现了,它的参数也是泛型的 Reduceable
s
case class CollectionReduceable[A, B](r1: Reduceable[A], r2: Reduceable[B])
extends Reduceable[CollectionReduceable[A, B]] {
override def reduceWith(
other: CollectionReduceable[A, B])
: CollectionReduceable[A, B] = CollectionReduceable(
r1 reduceWith other.r1,
r2 reduceWith other.r2
)
}
// error: type mismatch
// found : other.r1.type (with underlying type Reduceable[A])
// required: A
// r1 reduceWith other.r1,
// Desired outcome: same as CompoundCounter
我知道错误消息的来源 - 这是因为特征的 reduceWith
签名需要 other: A
,但如果我更改它,则 GenderCounter
和 FruitCounter
会断。什么可以改变我以实现我的预期结果?谢谢!!
尝试
case class CollectionReduceable[A <: Reduceable[A], B <: Reduceable[B]](r1: A, r2: B) extends Reduceable[CollectionReduceable[A, B]] {
override def reduceWith(other: CollectionReduceable[A, B]): CollectionReduceable[A, B] =
CollectionReduceable(
r1.reduceWith(other.r1),
r2.reduceWith(other.r2)
)
}
CollectionReduceable(GenderCounter(5, 10), FruitCounter(11, 2)) reduceWith CollectionReduceable(GenderCounter(5, 10), FruitCounter(11, 2))
// CollectionReduceable(GenderCounter(10,20),FruitCounter(22,4))
抱歉标题有点模糊,很难将我的问题概括为 single-liner。希望以下代码片段能更好地解释我的意图。
让我们首先为所有 Reduceable
:
trait Reduceable[A] {
def reduceWith(other: A): A
}
此类 Reduceable
事物的示例可以是这样的计数器:
case class GenderCounter(male: Int, female: Int)
extends Reduceable[GenderCounter] {
override def reduceWith(other: GenderCounter): GenderCounter =
GenderCounter(male + other.male, female + other.female)
}
case class FruitCounter(apples: Int, oranges: Int)
extends Reduceable[FruitCounter] {
override def reduceWith(other: FruitCounter): FruitCounter =
FruitCounter(apples + other.apples, oranges + other.oranges)
}
GenderCounter(5, 10) reduceWith GenderCounter(4, 11)
// res: GenderCounter = GenderCounter(9,21)
一个class以上面的计数器为参数,本身也可以是一个Reduceable
case class CompoundCounter(c1: GenderCounter, c2: FruitCounter)
extends Reduceable[CompoundCounter] {
override def reduceWith(
other: CompoundCounter)
: CompoundCounter = CompoundCounter(
c1 reduceWith other.c1,
c2 reduceWith other.c2
)
}
CompoundCounter(GenderCounter(5, 10), FruitCounter(11, 2)) reduceWith CompoundCounter(GenderCounter(5, 10), FruitCounter(11, 2))
// res: CompoundCounter = CompoundCounter(GenderCounter(10,20),FruitCounter(22,4))
但是,当我尝试引入一个泛型 Reduceable
class 时,问题出现了,它的参数也是泛型的 Reduceable
s
case class CollectionReduceable[A, B](r1: Reduceable[A], r2: Reduceable[B])
extends Reduceable[CollectionReduceable[A, B]] {
override def reduceWith(
other: CollectionReduceable[A, B])
: CollectionReduceable[A, B] = CollectionReduceable(
r1 reduceWith other.r1,
r2 reduceWith other.r2
)
}
// error: type mismatch
// found : other.r1.type (with underlying type Reduceable[A])
// required: A
// r1 reduceWith other.r1,
// Desired outcome: same as CompoundCounter
我知道错误消息的来源 - 这是因为特征的 reduceWith
签名需要 other: A
,但如果我更改它,则 GenderCounter
和 FruitCounter
会断。什么可以改变我以实现我的预期结果?谢谢!!
尝试
case class CollectionReduceable[A <: Reduceable[A], B <: Reduceable[B]](r1: A, r2: B) extends Reduceable[CollectionReduceable[A, B]] {
override def reduceWith(other: CollectionReduceable[A, B]): CollectionReduceable[A, B] =
CollectionReduceable(
r1.reduceWith(other.r1),
r2.reduceWith(other.r2)
)
}
CollectionReduceable(GenderCounter(5, 10), FruitCounter(11, 2)) reduceWith CollectionReduceable(GenderCounter(5, 10), FruitCounter(11, 2))
// CollectionReduceable(GenderCounter(10,20),FruitCounter(22,4))