[Swifty]mutatingを取り除く | Cocoa練習帳

[Swifty]mutatingを取り除く

ClassからStructに変更すると、プロパティを変更するメソッドにはmutatingキーワードをつけなければいけない。参考にしている発表では、これが格好悪いのでつける必要がない方法を選択したい。それが関数型プログラミング。SwiftではCopy-On-Writeに実装されていものがあるので、コストを気にしなくてもという事のようだ。

struct Deck {
    public func nextCard() -> Card {
        let card = Card()
        return card
    }
}
 
struct Hand {
    private let deck = Deck()
    private var cards = [Card]()
    
    public init(deck: Deck, cards: [Card]) {
        self.deck = deck
        self.cards = cards
    }
}

Handのプロパティcardsにカードを追加する場合、プロパティに変更を加えるメソッドを用意するのではなくて、内容をコピーして、カードを追加されたハンドを生成して返す。それとハンドを差し替えればいいじゃないの、という考えだ。

    private func insertCard(card: Card, at index: Int) -> Hand {
        var mutableCards = cards
        mutableCards.insert(card, at: index)
        return Hand(deck: deck, cards: mutableCards)
    }

これを利用すれば、新規カードの追加はこうなる。

    public func addNewCard(at index: Int) -> Hand {
        return insertCard(card: deck.nextCard(), at: index)
    }

カードの削除はこうだ。

    public func deleteCard(at index: Int) -> Hand {
        var mutableCards = cards
        mutableCards.remove(at: index)
        return Hand(deck: deck, cards: mutableCards)
    }

これらを組み合わせれば、カードの移動もこうなる。

    public func moveCard(fromIndex: Int, toIndex: Int) -> Hand {
        return deleteCard(at: fromIndex).insertCard(card: cards[fromIndex], at: toIndex)
    }

単なる配列操作だが、美しさを取るか!君はどっちだ!

ソースコード GitHubからどうぞ。
https://github.com/murakami/workbook/tree/master/ios/Hand - GitHub
関連情報 文化を調和させる
【Cocoa練習帳】 http://www.bitz.co.jp/weblog/
http://ameblo.jp/bitz/(ミラー・サイト)