【问题标题】:Updating immutable objects更新不可变对象
【发布时间】:2013-11-26 07:32:33
【问题描述】:

我构建了以下类:

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”字段加一,并返回新的“玩家列表”。

有没有更方便的方法来做到这一点?也许:

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)

谢谢!

【问题讨论】:

    标签: scala functional-programming purely-functional


    【解决方案1】:

    您可以将 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

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

    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

    【讨论】:

      猜你喜欢
      • 2013-07-07
      • 2021-09-18
      • 2019-11-12
      • 1970-01-01
      • 1970-01-01
      • 2014-08-18
      • 1970-01-01
      • 1970-01-01
      • 2017-08-16
      相关资源
      最近更新 更多