2012-04-24 80 views
2

我希望能够应用皮条客我的库模式来陈述,而不是行为。特别是,如果你在一个隐式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并覆盖木星是什么,或者拥有一个外部地图,该地图由getter & setter填充/读取。

我是斯卡拉的新手,我希望有一种更优雅的方式去做这样的事情。还不错,冥王星是一颗行星:)

+1

使用突变与皮条客,我的 - 库模式只是感觉不对。有点像宣称冥王星不是一颗行星。这是不对的。 – 2012-04-24 04:39:10

回答

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 
    } 
} 
3

让它在地球上val,只是模式匹配您有:

​​