更新不可变对象

时间:2013-11-26 07:32:33

标签: scala functional-programming purely-functional

我已经构建了以下类:

class Player(val name: String, val onField: Boolean, val draft: Int, val perc: Int, val height: Int, val timePlayed: Int) {
override def toString: String = name

}

我正在尝试

def play(team: List[Player]): List[Player] =
team map (p => new Player(p.name, p.onField, p.draft, p.perc, p.height, p.timePlayed + 1))

实际上将字段“timePlayed”递增1,并返回玩家的新“列表”。

有更方便的方法吗?也许:

def play(team: List[Player]): List[Player] =
team map (p => p.timeIncremented())

我的问题是如何以更方便的方式实现timeIncremented()?所以我不必这样做:

new Player(p.name, p.onField, p.draft, p.perc, p.height, p.timePlayed + 1)

谢谢!

1 个答案:

答案 0 :(得分:7)

您可以将define Player用作case class并使用编译器生成的方法copy

case class Player(name: String, onField: Boolean, draft: Int, perc: Int, height: Int, timePlayed: Int) {
    override def toString: String = name
}

def play(team: List[Player]): List[Player] =
    team map (p => p.copy(timePlayed = p.timePlayed + 1))

另外,如您所见,构造函数参数默认为val

您可以在timeIncremented中定义Player并完全按照您的意愿使用它:

case class Player(name: String, onField: Boolean, draft: Int, perc: Int, height: Int, timePlayed: Int) {
    override def toString: String = name
    def timeIncremented: Player = copy(timePlayed = this.timePlayed + 1)
}

def play(team: List[Player]): List[Player] =
    team map (_.timeIncremented)

对于更复杂的情况,您可以看一下镜头:
http://akisaarinen.fi/blog/2012/12/07/boilerplate-free-functional-lenses-for-scala/
Cleaner way to update nested structures