簡體   English   中英

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定義沖突。

更新:再多的隱式魔術也無法解決您的問題,因為這是一個編譯器類型問題,與隱式無關。

如果_selectedOption[Cell]類型,那么_selected.getCell類型,就編譯器而言,這就是故事的結尾。 如果這里實際上有一個底層子類型,則可以在運行時對其進行梳理。

_selected match {
  case Some(rc:RectangleCell) => place(rc,cell,this)
  case Some(ec:EnemyCell)     => place(ec,cell,this)
  case _ => //some default action
}

隱式是在編譯時解析的,因此它們無助於發現底層類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM