我有一個設計模式,其中有一個對象生成器(MorselGenerator及其子),其任何實例總是生成相同的確切類型的對象少量食物和它的孩子),但類型檢查員不會讓我對這些生成的物體中的兩個或多個進行任何操作,相信它們可能會有所不同。斯卡拉類型推斷未能注意到這些類型是相同的,無論它們是什麼
我怎樣才能讓這個過去的類型檢查?
trait Morsel
{
type M <: Morsel
def calories : Float
def + (v : M) : M
}
trait MorselGenerator
{
type Mg <: Morsel
def generateMorsel : Mg
}
class HotDog(c : Float, l : Float, w : Float) extends Morsel
{
type M = HotDog
val calories : Float = c
val length : Float = l
val width : Float = w
def + (v : HotDog) : HotDog = new HotDog(v.calories + calories, v.length + length, v.width + width)
}
class HotDogGenerator extends MorselGenerator
{
type Mg = HotDog
def generateMorsel : HotDog = new HotDog(500.0f, 3.14159f, 445.1f)
}
object Factory
{
def main (args : Array[String])
{
val hdGen = new HotDogGenerator()
println(eatTwo(hdGen))
}
def eatTwo (mGen : MorselGenerator)
{
val v0 : mGen.Mg = mGen.generateMorsel
val v1 : mGen.Mg = mGen.generateMorsel
v0 + v1 /// ERROR HERE
}
}
編譯器生成以下編譯錯誤
Generator.scala:43: error: type mismatch;
found : v1.type (with underlying type mGen.Mg)
required: v0.M
v0 + v1 /// ERROR HERE
^one error found
更新
這裏是C++代碼,那就是我想要做的更多或更少的等價物。請注意,eatTwo函數是完全多態的,並且沒有提及特定派生類型的Morsel或MorselGenerator。
#include <stdlib.h>
#include <stdio.h>
template <class M> class Morsel
{
public:
Morsel(float c) : calories(c) {}
float calories;
virtual M operator + (const M& rhs) const = 0;
};
template <class M> class MorselGenerator
{
public:
virtual M * generateMorsel() const = 0;
};
class HotDog : public Morsel<HotDog>
{
public:
HotDog(float c, float l, float w) : Morsel<HotDog>(c), length(l), width(w) {}
float length, width;
HotDog operator + (const HotDog& rhs) const
{ return HotDog(calories+rhs.calories, length+rhs.length, width+rhs.width); }
};
class HotDogGenerator : public MorselGenerator<HotDog>
{
HotDog * generateMorsel() const { return new HotDog(500.0f, 3.14159f, 445.1f); }
};
///////////////////////////////////////////////
template <class MorselType> float eatTwo (const MorselGenerator<MorselType>& mGen)
{
MorselType * m0 = mGen.generateMorsel();
MorselType * m1 = mGen.generateMorsel();
float sum = ((*m0) + (*m1)).calories;
delete m0; delete m1;
return sum;
}
int main()
{
MorselGenerator<HotDog> * morselStream = new HotDogGenerator();
printf("Calories Ingested: %.2f\n", eatTwo(*morselStream));
delete morselStream;
}
也許這將有助於:http://stackoverflow.com/questions/9198562/scala-self-type-and-this-type-in-collections-issue – tuxSlayer 2012-02-22 20:01:46