初始化对象为空(由于循环依赖?)
Initialized object is null (due to circular dependence?)
我有一个简单的语法
Expr -> Byte | Sum Expr Expr
下面的代码应该为其生成随机树
object randomTree extends App {
// Expr -> Byte | Sum Expr Expr
def intRnd(len: Int, start: Int = 0): Int = (math.random * len toInt) + start
def byteRnd = intRnd(256, -128)
case class Value[A](value: A, parent: Type) extends Type {
def gen = this
override def toString = value + ":" + parent.getClass.getSimpleName
}
trait Type {
def gen: Type //def gen[A]: Value[A]
override def toString = getClass.getSimpleName
}
class OR/*Enum*/(alternatives: Type*) extends Type {
def gen = alternatives(intRnd(alternatives.length)).gen
}
class AND/*Sequence*/(alternatives: Type*) extends Type {
def gen = {
println("Sum " + alternatives)// prints: Sum WrappedArray(null, null)
Value(alternatives.map(_.gen), this)
}
}
object Expr extends OR(Sum, Byte) {
override def gen = Value(super.gen, this)
}
//object Sum extends Type { // everything is fine if this Sum is used
//def gen = Value(Expr.gen -> Expr.gen, this) }
println("Expr = " + Expr) // prints: Expr = Expr$
object Sum extends AND(Expr, Expr) // this Sum causes NPE
object Byte extends Type {
def gen = Value(byteRnd, this)
}
(1 to 10) foreach { i=> println(Expr.gen) }
}
我想知道为什么 object Sum extends AND(Expr, Expr)
扩展为 AND(WrappedArray(null, null))
,因为 Expr 是一个非空对象,我如何初始化 Expr 以使 Sum 正确?
由于 Expr
和 Sum
之间存在 循环引用 ,这导致了 空值 ,By Name Parameter可用于解决此循环引用问题以延迟对象的初始化。喜欢:
...
class OR /*Enum*/ (alternatives: => Array[Type]) extends Type {
...
class AND /*Sequence*/ (alternatives: => Array[Type]) extends Type {
...
上面代码中:alternatives: => Array[Type]
作为By Name参数来延迟循环对象的初始化时间,避免空值。
我有一个简单的语法
Expr -> Byte | Sum Expr Expr
下面的代码应该为其生成随机树
object randomTree extends App {
// Expr -> Byte | Sum Expr Expr
def intRnd(len: Int, start: Int = 0): Int = (math.random * len toInt) + start
def byteRnd = intRnd(256, -128)
case class Value[A](value: A, parent: Type) extends Type {
def gen = this
override def toString = value + ":" + parent.getClass.getSimpleName
}
trait Type {
def gen: Type //def gen[A]: Value[A]
override def toString = getClass.getSimpleName
}
class OR/*Enum*/(alternatives: Type*) extends Type {
def gen = alternatives(intRnd(alternatives.length)).gen
}
class AND/*Sequence*/(alternatives: Type*) extends Type {
def gen = {
println("Sum " + alternatives)// prints: Sum WrappedArray(null, null)
Value(alternatives.map(_.gen), this)
}
}
object Expr extends OR(Sum, Byte) {
override def gen = Value(super.gen, this)
}
//object Sum extends Type { // everything is fine if this Sum is used
//def gen = Value(Expr.gen -> Expr.gen, this) }
println("Expr = " + Expr) // prints: Expr = Expr$
object Sum extends AND(Expr, Expr) // this Sum causes NPE
object Byte extends Type {
def gen = Value(byteRnd, this)
}
(1 to 10) foreach { i=> println(Expr.gen) }
}
我想知道为什么 object Sum extends AND(Expr, Expr)
扩展为 AND(WrappedArray(null, null))
,因为 Expr 是一个非空对象,我如何初始化 Expr 以使 Sum 正确?
由于 Expr
和 Sum
之间存在 循环引用 ,这导致了 空值 ,By Name Parameter可用于解决此循环引用问题以延迟对象的初始化。喜欢:
...
class OR /*Enum*/ (alternatives: => Array[Type]) extends Type {
...
class AND /*Sequence*/ (alternatives: => Array[Type]) extends Type {
...
上面代码中:alternatives: => Array[Type]
作为By Name参数来延迟循环对象的初始化时间,避免空值。