class Entity(val id:String){
override def toString = id
}
class RequirementType
case class DependsEither(t:List[(Entity,Int)]) extends RequirementType
case class Depends(t:(Entity,Int)) extends RequirementType
class BuildableEntity(override val id:String,
val mineralCost:Int,
val gasCost:Int,
val buildTime:Int,
val buildCount:Int,
val supplyCount:Int,
val req:List[RequirementType],
val onBuildStart: GameState => GameState,
val onBuildFinish: GameState => GameState
)extends Entity(id)
class SimpleBuilding(id:String,
mineralCost:Int,
gasCost:Int,
buildTime:Int,
req:List[RequirementType]
) extends BuildableEntity(id,mineralCost,gasCost,buildTime,1,0,req:::List(ConsumesOnStart((Drone,1))),{s=>s},{x=>x})
object SpawningPool extends SimpleBuilding("spawningPool",200,0,65,List(DependsEither(List((Hatchery,1),(Lair,1),(Hive,1)))))
object Lair extends SimpleBuilding("lair",150,100,80,List(ConsumesOnFinish(Hatchery,1),Depends(SpawningPool,1)))
object InfestationPit extends SimpleBuilding("infestationPit",100,100,50,List(DependsEither(List((Lair,1),(Hive,1)))))
现在,当我调用println(Lair.req)时,它有时会打印为
列表(ConsumesOnFinish((孵化场,1)),取决于((null,2)),ConsumesOnStart((无人机,1)))
有时候是
列表(ConsumesOnFinish((孵化,1)), 取决于((spawningPool,2)),ConsumesOnStart((无人机,1)))
如果有人知道可能出现什么问题,我会永远爱你。我不知道为什么它会这样做。我有更多的SimpleBuilding扩展,但它们似乎正常工作
编辑: 我还要提一下,编译后结果会发生变化。我的意思是,当我运行单元测试时,它有时会显示为null,有时也会显示为正确的实例。
答案 0 :(得分:3)
Lair
在其构造函数中使用SpawningPool
并相互提升。但那时,另一个不存在。
答案 1 :(得分:3)
你在构造函数中有递归定义,虽然我相信它是支持的,但它看起来像是出了问题。你可以试试懒惰的vals,看看问题是否消失了?也就是说,
object X extends C("this",that,1) { /* code */ }
变为
lazy val X = new C("this",that,1) { /* code */ }
答案 2 :(得分:3)
这确实是循环依赖和初始化的情况。以下是您问题的简短版本:
class X(val x: List[X])
object A extends X(List(B))
object B extends X(List(A))
object Main {
def main(args:Array[String]) {
println("A.x: " + A.x)
println("B.x: " + B.x)
}
}
这将打印出来:
$ scala -cp classes Main
A.x: List(B$@143c8b3)
B.x: List(null)
您可以使用names参数来允许在使用对象之前完成对象构建:
class X(x0: => List[X]) {
lazy val x = x0
}
object A extends X(List(B))
object B extends X(List(A))
修复程序适用于小测试用例:
$ scala -cp classes Main
A.x: List(B$@1feca64)
B.x: List(A$@6d084b)
根据此情况,您可能希望将req:List[RequirementType]
更改为req0: => List[RequirementType]
并添加lazy val req = req0
。
如果这对你有用,我们应该重新提出问题,提到对象初始化和循环依赖。请注意,这与this question/answer非常相似。