Menu
Coddy logo textTech

mutatingメソッド

CoddyのSwiftジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 9/57。

プロパティを変更する構造体のメソッドには、mutatingを付ける必要があります。このキーワードがないとメソッドはコンパイルできません。これは、値型のメソッドではselfが定数として扱われるためです。

struct Counter {
    var count = 0

    mutating func increment() {
        count += 1
    }
}

var c = Counter()
c.increment()
c.increment()
print(c.count)

出力:

2

mutatingメソッドはvarに対してのみ呼び出せます。let定数では、値全体が固定されているため、呼び出しはコンパイルできません。

var a = Counter()
a.increment()        // 問題なし

let b = Counter()
// b.increment()     // error: b は let 定数です

プロパティを読み取るだけのメソッドは非変更のままで、定数に対しても使用できます。優れた設計では、変更を行うメソッドを少数に限定します。

struct Stack {
    var items: [Int] = []

    mutating func push(_ x: Int) { items.append(x) }
    mutating func pop() -> Int? { items.popLast() }
    func peek() -> Int? { items.last }
}

var s = Stack()
s.push(3)
s.push(8)
print(s.pop() ?? -1)
print(s.peek() ?? -1)

出力:

8
3

変更可能なメソッドはself全体を置き換えることができるため、値をリセットするのに便利です:

struct Score {
    var points = 0
    var bonus = 0

    mutating func reset() {
        self = Score()
    }
}

var s = Score(points: 10, bonus: 3)
s.reset()
print(s.points + s.bonus)

出力:

0
challenge icon

チャレンジ

簡単

構造体 Wallet を完成させてください。add(_:) と spend(_:) は変更を伴います。spend は十分なお金が残っている場合にのみ減算し、減算を実行したかどうかを返します。report() は変更を伴わず、balance 40 を返します。

提供されたコードは +n および -n のコマンドを読み取り、1つの var wallet に適用し、支出が拒否された場合は denied を出力し、最後に report() を出力します。

コードは Wallet.swift に記述してください。main.swift には提供された入出力コードが含まれており、編集できません。

自分で試してみよう

// 提供された入出力コード: そのままにしておく
var input: [String] = []
while let line = readLine() { input.append(line) }
var wallet = Wallet()
for cmd in input {
    let amount = Int(cmd.dropFirst())!
    if cmd.hasPrefix("+") {
        wallet.add(amount)
    } else if !wallet.spend(amount) {
        print("denied")
    }
}
print(wallet.report())
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Swiftプレイグラウンド