我希望能够将pimp-my-library模式应用于状态,而不是行为。具体来说,如果您在隐式def中定义var,设置它,然后尝试读取它,状态就会丢失。我把一个人为的例子拼凑在一起:
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并覆盖木星是什么,或者有一个外面的地图,由吸气剂填充/读取&安培;设定器。
我对Scala很陌生,我希望有更优雅的方式来做这样的事情。也是的,冥王星是一颗行星:)
答案 0 :(得分: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
}
}
答案 1 :(得分:3)
将它设为val
并在您拥有的星球上进行模式匹配:
implicit def pimpPlanet(planet: Planet) = {
new {
var distanceFromSun: Int = planet match {
case Planet("Earth") => 1
case Planet("Jupiter") => 5
}
}
}
等