0Pricing
Swift Academy · レッスン

非変更の代替手段

その場で変更する代わりに、新しい値を返します。

「非変更の代替手段」はCoddyKit上の無料Swift Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSwift Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Swift Academyコースには全4レッスンが含まれています。

変更せずに返す

インスタンスをその場で変更する代わりに、非 mutating メソッドから変更を適用したまったく新しい値を返すことができます。

struct Counter {
    var value: Int
    func incremented() -> Counter {
        return Counter(value: value + 1)
    }
}
let c = Counter(value: 0)
let next = c.incremented()
print(c.value, next.value)

元の値は変更されない

何も変更しないため、元の値は保持され、新しい値が生成されます。

struct Vector {
    var x: Int
    var y: Int
    func scaled(by factor: Int) -> Vector {
        return Vector(x: x * factor, y: y * factor)
    }
}
let v = Vector(x: 2, y: 3)
let big = v.scaled(by: 10)
print(v.x, v.y, big.x, big.y)

let のインスタンスでも動作する

非 mutating メソッドはレシーバーを変更しないため、let 定数に対して呼び出せます。

struct Money {
    var cents: Int
    func plus(_ other: Int) -> Money {
        return Money(cents: cents + other)
    }
}
let m = Money(cents: 100)
print(m.plus(50).cents)

命名規則

Swift の慣例では、mutating メソッドには命令形の動詞(sort)を使い、非 mutating メソッドには過去分詞形または -ed/-ing 形(sorted)を使います。

var nums = [3, 1, 2]
let ordered = nums.sorted()
nums.sort()
print(ordered, nums)

sorted と sort の違い

標準ライブラリもこの慣例に従っています。sorted() は新しい配列を返し、sort() は配列をその場で変更します。

let a = [5, 2, 8, 1]
let b = a.sorted()
print(a)
print(b)

reversed と reverse の違い

同様に、reversed() は非 mutating です。ここでは Array を使って配列に実体化します。

let a = [1, 2, 3]
let b = Array(a.reversed())
print(a, b)

非 mutating 呼び出しの連結

非 mutating メソッドは値を返すため、流れるように連結して呼び出せます。

let result = [4, 2, 9, 1].sorted().map { $0 * 2 }
print(result)

関数型スタイル

変更する代わりに新しい値を返すと、テストや動作の把握がしやすい関数型スタイルを実現できます。

struct Account {
    var balance: Int
    func deposited(_ n: Int) -> Account {
        return Account(balance: balance + n)
    }
}
let a0 = Account(balance: 0)
let a1 = a0.deposited(100).deposited(50)
print(a0.balance, a1.balance)

共有状態のバグを避ける

新しい値を生成すると、意図しない共有状態の変更を避けられます。これは特にスレッド間で有用です。

struct Settings {
    var volume: Int
    func with(volume newVolume: Int) -> Settings {
        return Settings(volume: newVolume)
    }
}
let base = Settings(volume: 5)
let loud = base.with(volume: 11)
print(base.volume, loud.volume)

変更したほうがよい場合

ループ内で1つのインスタンスを繰り返し更新する場合は、多数のコピーを作成するよりも、その場で変更するほうが効率的です。

var total = 0
for n in 1...5 {
    total += n
}
print(total)

両方を提供する

標準ライブラリのように、適切に設計された型では両方の形式を提供することがあります。呼び出し側は、変更するか新しい値を作るかを選べます。

struct Text {
    var value: String
    func uppercased() -> Text {
        return Text(value: value.uppercased())
    }
    mutating func uppercase() {
        value = value.uppercased()
    }
}
var t = Text(value: "hi")
let u = t.uppercased()
t.uppercase()
print(u.value, t.value)

クイックチェック

非 mutating の設計を確認しましょう。

まとめ

変更の代わりに、非 mutating メソッドは変更を適用した新しい値を返し、元の値をそのまま保持します。また、let のインスタンスでも使用できます。Swift の慣例では、命令形の名前(sort)と -ed/-ing 形の名前(sorted)を使い分けます。

let a = [3, 1, 2]
let b = a.sorted()
print(a, b)

よくある質問

「非変更の代替手段」レッスンは無料ですか?

はい。「非変更の代替手段」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Swift Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Swift Academyコースには全4レッスンが含まれています。

「非変更の代替手段」で何を学びますか?

その場で変更する代わりに、新しい値を返します。 ブラウザで直接実行するハンズオンコードでSwift Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Swift Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのSwift Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「非変更の代替手段」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このSwift Academyレッスンでコードを書いて実行できますか?

はい。すべてのSwift Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 値型と不変性
  2. mutatingキーワード
  3. mutatingとselfの再代入
  4. 非変更の代替手段
← Swift Academyに戻る