我有一个Operator
抽象类:
abstract class Operator[T, U] {
def setParent(op: Operator[T, U]): Unit
def newOp(): Operator[Byte, String] = {
val newOperator = new NewOperator[Byte, String]
newOperator.setParent(this)
newOperator
}
}
和另一个NewOperator
类
class NewOperator[T, U] extends Operator[T, U] {
var parent: Operator[T,U] = null
def setParent(op: Operator[T, U]): Unit = {this.parent = op}
}
现在,在课程newOp()
的{{1}}方法的第二行,我收到错误
Operator
说:newOperator.setParent(this)
^
。
解决此问题的唯一方法是将Type mismatch: expected: Operator[Byte, String], actual: Operator[T, U]
添加到.instanceOf[Operator[Byte, String]]
吗?
this
答案 0 :(得分:1)
为什么不让方法newOp
通用?
abstract class Operator[T, U] {
def setParent(op: Operator[T, U]): Unit
def newOp(): Operator[T, U] = {
val newOperator = new NewOperator[T, U]
newOperator.setParent(this)
newOperator
}
}
class NewOperator[T, U] extends Operator[T, U] {
var parent: Operator[T,U] = null
def setParent(op: Operator[T, U]): Unit = {this.parent = op}
}
val op = new NewOperator[Byte, String]().newOp
答案 1 :(得分:1)
您当前的解决方案限制所有运算符[Byte,String]具有Operator [Byte,String]父类型(如果您使用asInstanceOf
,则只能在运行时找到它)。
一般情况下,如果父/子泛型类型可能不同,请使用:
scala> :paste
// Entering paste mode (ctrl-D to finish)
class Operator[T, U, P <: Operator[_, _, _]] {
var parent: P = null.asInstanceOf[P]
def setParent(op: P): Unit = {this.parent = op}
def newOp[TT, UU]() = {
val newOperator = new Operator[TT, UU, Operator[T, U, P]]()
newOperator.setParent(this)
newOperator
}
}
// Exiting paste mode, now interpreting.
defined class Operator
scala> new Operator[Byte, String, Null]
res19: Operator[Byte,String,Null] = Operator@5470e2f4
scala> res19.newOp[Int, String]
res20: Operator[Int,String,Operator[Byte,String,Null]] = Operator@729c1e43
scala> res20.parent
res21: Operator[Byte,String,Null] = Operator@5470e2f4
如果您需要为运营商提供一些特定的状态/方法,您可以将newOp
移动到某个子类并使运营商成为特征。
或者您可以将类型类用于特定于操作员的操作:
scala> new Operator[Byte, String, Null]
res23: Operator[Byte,String,Null] = Operator@728b49e2
scala> implicit class ByteOperator(o: Operator[Byte, String, _]) {
| def hello = "hello" //here you can access some members of Operator
| }
defined class ByteOperator
scala> res23.hello
res24: String = hello
如果您确实需要与父母具有相同通用性的孩子:
scala> :paste
// Entering paste mode (ctrl-D to finish)
class Operator[T, U] {
var parent: Operator[T, U] = null
def newInstance: Operator[T, U] = new Operator[T, U]
def newOp: Operator[T, U] = {
val newOperator = newInstance
newOperator.setParent(this)
newOperator
}
def setParent(op: Operator[T, U]): Unit = {this.parent = op}
}
// Exiting paste mode, now interpreting.
defined class Operator
scala> new Operator[Byte, String]
res15: Operator[Byte,String] = Operator@4e6ea769
scala> res15.newOp
res16: Operator[Byte,String] = Operator@c774157
scala> res16.parent
res17: Operator[Byte,String] = Operator@4e6ea769
如果你只需要建模一些AST(抽象语法树),case classess可能是一个很好的解决方案:
trait Expression[T] {
def v: T
}
case class Value[T](v: T) extends Expression[T]
case class Plus[T1, T2](a: Expression[T1], b: Expression[T2])(implicit wrap: T1 => Arithmetic[T1, T2]) extends Expression[T1] {
def v = wrap(a.v) ++ b.v
}
abstract class Arithmetic[T1, T2](v: T1) {
def ++ (v: T2): T1
}
implicit class ArithmeticInt(val v: Int) extends Arithmetic[Int, Int](v) {
def ++ (v2: Int) = v + v2
}
implicit class ArithmeticIntDouble(val v: Int) extends Arithmetic[Int, Double](v) {
def ++ (v2: Double) = (v.toDouble + v2).toInt
}
scala> Plus(Value(5.0), Value(11.0)).v
res57: Value[Double] = Value(16.0)
scala> Plus(Value(5), Value(11.0)).v
res67: Int = 16
scala> Plus(Value(5), Value(6)).v
res68: Int = 11
scala> Plus(Value(5.0), Value(6)).v
<console>:60: error: No implicit view available from Double => Arithmetic[Double,Int].
Plus(Value(5.0), Value(6)).v
^
答案 2 :(得分:0)
而不是像这样做
newOperator.setParent(this) in abstract class operator you can do something like this
newOperator.setParent(newOperator)
这将解决您的问题