Mat*_*t R 19 inheritance scala immutability
我希望能够根据具体类可能具有的各种属性从特征组装域对象.当我的对象是可变的时,这非常简单.例如:
trait HasHitPoints { var hitPoints: Int = 100 }
trait HasBearing { var bearing: Double = 0 }
class Ship extends HasHitPoints with HasBearing
class Base extends HasHitPoints
val entities = new Ship :: new Base :: Nil
entities.collect { case h: HasHitPoints => h.hitPoints += 10 }
Run Code Online (Sandbox Code Playgroud)
特别是,我可以在HasHitPoints不知道具体类型的情况下以多态方式读取或更新任何实例.
使用不可变对象实现此操作的最佳方法是什么?如果我很高兴只阅读属性,那么我可以做类似的事情:
trait HasHitPoints { val hitPoints: Int }
trait HasBearing { val bearing: Double }
case class Ship(hitPoints: Int, bearing: Double) extends HasHitPoints with HasBearing
case class Base(hitPoints: Int) extends HasHitPoints
val things = Ship(50, 0) :: Base(100) :: Nil
val totalHitPoints = things.collect { case h: HasHitPoints => h.hitPoints }.sum
Run Code Online (Sandbox Code Playgroud)
此外,copy如果我知道精确类型,我可以轻松修改具体类.例如,困难的部分是更新任意HasHitPoints.如果我有很多具体的类,以及许多不同的属性,我可能想要混合使用,避免样板代码爆炸的最佳方案是什么?
您可能会幸运地向您的特征添加一个例如抽象 def withHitPoints(points: Int) 方法,该方法返回具有不同属性值的容器对象的副本。这将使用量减少为:
val damagedActors = actors map { actor => actor.withHitPoints( actor.hitPoints - 10 ) }
Run Code Online (Sandbox Code Playgroud)
但否则将需要每个具体类的每个属性一个额外的方法,所以我不确定它是否真正解决了您的问题。对于像 Scala 这样的静态语言来说,这感觉不太合适(我也不太可能为这个特定用例的不变性而烦恼);这里的不可变解决方案可能是动态语言的更好候选者。
| 归档时间: |
|
| 查看次数: |
1084 次 |
| 最近记录: |