C++が分かる人向けにSwiftのstructとclassの違いを整理する
Swiftでは struct をかなりよく使います。
C++経験者だと、struct と class はアクセス指定のデフォルトが違うくらい、という感覚が残っているかもしれません。
Swiftではそこがかなり違います。
公式でも、structures and classesは似た機能を持つ一方で、classには継承や参照セマンティクスがあると説明されています。
https://docs.swift.org/swift-book/documentation/the-swift-programming-language/classesandstructures/
structは値型
Swiftの struct は値型です。
struct Point {
var x: Int
var y: Int
}
var a = Point(x: 1, y: 2)
var b = a
b.x = 10
print(a.x) // 1
print(b.x) // 10
b = a で同じものを参照しているわけではありません。
C++の普通の値コピーに近いです。
Point a{1, 2};
Point b = a;
b.x = 10;
classは参照型
Swiftの class は参照型です。
final class Counter {
var value = 0
}
let a = Counter()
let b = a
b.value = 10
print(a.value) // 10
a と b は同じインスタンスを指しています。
C++でいうポインタや shared_ptr 的な共有参照に近い感覚です。
mutatingが必要になる
Swiftのstructで自分自身を書き換えるメソッドには mutating が必要です。
struct Counter {
var value = 0
mutating func increment() {
value += 1
}
}
これは「このメソッドは値を変更する」という印です。
C++では非constメンバ関数なら変更できますが、Swiftではstructのメソッドはデフォルトでselfを変更できません。
まずstructで考える
Swiftでは、データを表す型はまずstructで作ることが多いです。
struct User {
let id: Int
var name: String
}
classにするのは、参照として共有したい理由がある場合です。
- 同じインスタンスを複数箇所から更新したい
- 継承が必要
- Objective-CやAppleフレームワークとの都合がある
- identityを扱いたい
このあたりがないなら、structで十分なことが多いです。
まとめ
Swiftの struct と class は、C++より意味の差が大きいです。
structは値型classは参照型- structで自身を変更するメソッドには
mutating - データ表現はまずstructで考える
- 共有・継承・identityが必要ならclassを使う
C++の struct/class の違いを持ち込むより、「値として扱うか、参照として共有するか」で見ると整理しやすいです。


