Scala 隐式
Scala implicits
我正在尝试了解如何在 Scala 中使用隐式:
在我的代码中我有:
trait Cell
class EnemyCell extends Cell
class RectangleCell extends Serializable with Cell
我定义了一个 trait Placeable 并且我希望它有一个 cell 的子类型
trait Placeable[A <: Cell] {
def place(a: A, cell:Option[RectangleCell],controller:MapController ): Unit
}
然后我定义了对象:
object Placeable {
//Apply
def apply[A <: Cell](implicit pleaceable: Placeable[A ]): Placeable[A] = pleaceable
def place[A: Placeable](a: A, cell:Option[RectangleCell], controller:MapController) = Placeable[A].place(a, cell, controller)
def instance[A <: Cell](func: (A, Option[RectangleCell], MapController) => Unit): Placeable[A] =
new Placeable[A] {
def place(a: A, cell:Option[RectangleCell] , controller: MapController): Unit = func(a, cell, controller)
}
//These 2 def does not seem to do anything...
implicit def cellToEnemyCell(cell: Cell): EnemyCell = cell.asInstanceOf[EnemyCell];
implicit def cellToRectangleCell(cell: Cell): RectangleCell = cell.asInstanceOf[RectangleCell];
implicit val rectanglePlaceable: Placeable[RectangleCell] =
instance((selected, cell, controller) => {
...
})
implicit val enemyPlaceable: Placeable[EnemyCell] =
instance((selected, cell, controller) => {
...
})
}
问题是我收到错误:
Error:(75, 98) type arguments [A] do not conform to method apply's type parameter bounds [A <: model.Cell]
def place[A: Placeable](a: A, cell:Option[RectangleCell], controller:MapController) = Placeable[A].place(a, cell, controller)
我只想使用:
var _selected:Option[Cell] = Option.empty; //I edit this in my code and it can be either a RectangleCell or a EnemyCell
...
val tmpRect = _selected.get
place(tmpRect,cell,this)
而不是做:
if(_selected.get.isInstanceOf[RectangleCell]) {
val tmpRect = _selected.get.asInstanceOf[RectangleCell]
place(tmpRect,cell,this)
} else {
val tmpRect = _selected.get.asInstanceOf[EnemyCell]
place(tmpRect,cell,this)
}
提前致谢!
这是使其能够编译的修复程序。
def place[A <: Cell :Placeable](...
我不确定它是否能让你到达你想去的地方(_selected
?)但至少它可以编译。
错误原因如下。 (我将使用不同的类型参数名称。一遍又一遍地重复使用 A
可能会造成混淆,因为它们不一定意味着相同的东西。)
trait Placeable[C <: Cell] {...
- Placeable
类型参数仅限于 Cell
或其子类型。
def place[P: Placeable](...
- 隐式作用域中必须有可用的 Placeable[P]
。但是 P
不受限制。这与 Placeable
定义冲突。
更新:再多的隐式魔术也无法解决您的问题,因为这是一个编译器类型问题,与隐式无关。
如果 _selected
是 Option[Cell]
类型,那么 _selected.get
是 Cell
类型,就编译器而言,这就是故事的结尾。如果这里实际上有一个潜在的子类型,那么可以在 运行 时间梳理出来。
_selected match {
case Some(rc:RectangleCell) => place(rc,cell,this)
case Some(ec:EnemyCell) => place(ec,cell,this)
case _ => //some default action
}
隐式是在编译时解析的,因此它们无法帮助发现底层类型。
我正在尝试了解如何在 Scala 中使用隐式: 在我的代码中我有:
trait Cell
class EnemyCell extends Cell
class RectangleCell extends Serializable with Cell
我定义了一个 trait Placeable 并且我希望它有一个 cell 的子类型
trait Placeable[A <: Cell] {
def place(a: A, cell:Option[RectangleCell],controller:MapController ): Unit
}
然后我定义了对象:
object Placeable {
//Apply
def apply[A <: Cell](implicit pleaceable: Placeable[A ]): Placeable[A] = pleaceable
def place[A: Placeable](a: A, cell:Option[RectangleCell], controller:MapController) = Placeable[A].place(a, cell, controller)
def instance[A <: Cell](func: (A, Option[RectangleCell], MapController) => Unit): Placeable[A] =
new Placeable[A] {
def place(a: A, cell:Option[RectangleCell] , controller: MapController): Unit = func(a, cell, controller)
}
//These 2 def does not seem to do anything...
implicit def cellToEnemyCell(cell: Cell): EnemyCell = cell.asInstanceOf[EnemyCell];
implicit def cellToRectangleCell(cell: Cell): RectangleCell = cell.asInstanceOf[RectangleCell];
implicit val rectanglePlaceable: Placeable[RectangleCell] =
instance((selected, cell, controller) => {
...
})
implicit val enemyPlaceable: Placeable[EnemyCell] =
instance((selected, cell, controller) => {
...
})
}
问题是我收到错误:
Error:(75, 98) type arguments [A] do not conform to method apply's type parameter bounds [A <: model.Cell]
def place[A: Placeable](a: A, cell:Option[RectangleCell], controller:MapController) = Placeable[A].place(a, cell, controller)
我只想使用:
var _selected:Option[Cell] = Option.empty; //I edit this in my code and it can be either a RectangleCell or a EnemyCell
...
val tmpRect = _selected.get
place(tmpRect,cell,this)
而不是做:
if(_selected.get.isInstanceOf[RectangleCell]) {
val tmpRect = _selected.get.asInstanceOf[RectangleCell]
place(tmpRect,cell,this)
} else {
val tmpRect = _selected.get.asInstanceOf[EnemyCell]
place(tmpRect,cell,this)
}
提前致谢!
这是使其能够编译的修复程序。
def place[A <: Cell :Placeable](...
我不确定它是否能让你到达你想去的地方(_selected
?)但至少它可以编译。
错误原因如下。 (我将使用不同的类型参数名称。一遍又一遍地重复使用 A
可能会造成混淆,因为它们不一定意味着相同的东西。)
trait Placeable[C <: Cell] {...
-Placeable
类型参数仅限于Cell
或其子类型。def place[P: Placeable](...
- 隐式作用域中必须有可用的Placeable[P]
。但是P
不受限制。这与Placeable
定义冲突。
更新:再多的隐式魔术也无法解决您的问题,因为这是一个编译器类型问题,与隐式无关。
如果 _selected
是 Option[Cell]
类型,那么 _selected.get
是 Cell
类型,就编译器而言,这就是故事的结尾。如果这里实际上有一个潜在的子类型,那么可以在 运行 时间梳理出来。
_selected match {
case Some(rc:RectangleCell) => place(rc,cell,this)
case Some(ec:EnemyCell) => place(ec,cell,this)
case _ => //some default action
}
隐式是在编译时解析的,因此它们无法帮助发现底层类型。