トップ «前の日記(2016-12-08) 最新 次の日記(2016-12-10)» 編集

Cocoa練習帳

iOS/iPhone/iPad/watchOS/tvOS/MacOSX/Android プログラミング, Objective-C, Cocoa, Swiftなど

2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|

2016-12-09 [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/(ミラー・サイト)

トップ «前の日記(2016-12-08) 最新 次の日記(2016-12-10)» 編集