2

動作ではなく、pimp-my-libraryパターンをstateに適用できるようにしたいと思います。具体的には、暗黙のdefで変数を定義し、それを設定してから読み取ろうとすると、状態が失われます。私は不自然な例をまとめました:

class Planet(val name: String)

object SolarSystem {
  val Mercury = new Planet("Mercury")
  val Venus = new Planet("Venus")
  val Earth = new Planet("Earth")
  val Mars = new Planet("Mars")
  val Jupiter = new Planet("Jupiter")
  val Saturn = new Planet("Saturn")
  val Uranus = new Planet("Uranus")
  val Neptune = new Planet("Neptune")
  val Pluto = new Planet("Pluto")
}

object Pimper {
  implicit def pimpPlanet(planet: Planet) = {
    new {
      var distanceFromSun: Int = 0
    }
  }

  import SolarSystem._

  Jupiter.distanceFromSun = 5 // AU
}

object Main {
  def main(args: Array[String]) {
    import SolarSystem._
    import Pimper._

    println(Jupiter.distanceFromSun)
  }
}

当然、これは0を出力しますが、5を出力したいと思います。SolarSystemを拡張してJupiterをオーバーライドする、またはゲッターとセッターがデータを入力/読み取る外部のマップを作成するなど、いくつかの解決策を検討しました。

私はScalaにかなり慣れていないので、このようなことを行うためのよりエレガントな方法があることを望んでいました。また、はい、冥王星は惑星です:)

4

2 に答える 2

5
object Pimper { 

  var planets = Map.empty[Planet, EnhancedPlanet]
  class EnhancedPlanet(var distance: Int)

  implicit def pimpPlanet(planet: Planet) = planets.get(planet).getOrElse {
    planets += planet -> new EnhancedPlanet(0)
    planets(planet)
  }

}

object Main {
  def main(args: Array[String]) {
    import SolarSystem._
    import Pimper._

    println(Jupiter.distance) //0
    Jupiter.distance = 5
    println(Jupiter.distance) //5
  }
}
于 2012-04-24T02:58:19.880 に答える
3

それを作って、valあなたが持っている惑星でちょうどパターンマッチしてください:

implicit def pimpPlanet(planet: Planet) = {
  new {
    var distanceFromSun: Int = planet match {
      case Planet("Earth") => 1
      case Planet("Jupiter") => 5
    }
  }
}

于 2012-04-24T02:54:47.597 に答える