Menu
Coddy logo textTech

構造体かクラス

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

Swiftのガイドラインは、まず構造体から始めることです。そして、クラスにしかできないことが必要な場合にのみクラスを選びます。構造体はより単純です。各変数がそれぞれ自身の値を所有するため、ある場所での変更が別の場所のコードを予期せず驚かせることはありません。

struct Temperature {
    var celsius: Double
}

var today = Temperature(celsius: 21)
var yesterday = today
yesterday.celsius = 18
print(today.celsius)

出力:

21.0

1つのオブジェクトを共有する必要がある場合は、クラスを選びます。たとえば、1つの銀行口座を複数の画面で使用する場合のように、プログラムの複数の部分が同じ変化する状態を参照する必要があるケースです。クラスは、structにはない継承もサポートします。

class SharedLog {
    var lines: [String] = []
}

let log = SharedLog()
let moduleA = log
let moduleB = log
moduleA.lines.append("A started")
moduleB.lines.append("B started")
print(log.lines.count)

出力:

2

構造体では == を無料で利用できます。宣言に Equatable を追加すると、Swift はすべてのプロパティを比較します。一方、クラスでは === を使って同一性を比較します。

struct Point: Equatable {
    var x: Int
    var y: Int
}

print(Point(x: 1, y: 2) == Point(x: 1, y: 2))
print(Point(x: 1, y: 2) == Point(x: 2, y: 1))

出力:

true
false

簡単な確認です。同じデータを持つ2つの項目を同じものとして数えるべき場合(点、価格、日付など)は、structを使います。別の項目とデータが一致していても重要なアイデンティティを持つ場合(ユーザーアカウント、開いているファイルなど)は、classを使います。

struct Money { var cents: Int }          // 500セントは500セントです
class UserAccount {                      // 2つのアカウントは名前を共有できる
    let id: Int
    var name: String
    init(id: Int, name: String) { self.id = id; self.name = name }
}
challenge icon

チャレンジ

簡単

Point は == で比較できる構造体にしてください。適合を追加し、リスト内の異なる点の数を返す countDistinct(_:) を完成させてください(2つの点は、両方の座標が一致するときに同じものとみなします)。

提供されたコードは、1行につき1つの点を x,y として読み取り、個数とともに distinct: を出力します。

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

自分で試してみよう

// 提供された入出力コード: そのままにしておく
var input: [String] = []
while let line = readLine() { input.append(line) }
let points = input.map { line -> Point in
    let p = line.split(separator: ",").map { Int($0)! }
    return Point(x: p[0], y: p[1])
}
print("distinct: \(countDistinct(points))")
quiz icon腕試し

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

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

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