値セマンティクス
CoddyのSwiftジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 8/57。
構造体は値型です。構造体を別の変数に代入すると、そのコピーが作成されます。クラスとは異なり、コピーを変更しても元の構造体は変更されません。
struct Point {
var x: Int
}
var a = Point(x: 1)
var b = a
b.x = 99
print(a.x)
print(b.x)出力:
1
99クラスを使った同じ比較では、その違いがわかります。両方の変数が1つのオブジェクトを参照しています。
class PointRef {
var x: Int
init(x: Int) { self.x = x }
}
let a = PointRef(x: 1)
let b = a
b.x = 99
print(a.x)出力:
99構造体を関数に渡すと、コピーも渡されます。パラメータは定数なので、変更されたバージョンを返すために、関数はローカルコピーを作成して返します:
struct Point {
var x: Int
}
func shifted(_ p: Point, by dx: Int) -> Point {
var copy = p
copy.x += dx
return copy
}
let start = Point(x: 1)
let moved = shifted(start, by: 4)
print(start.x)
print(moved.x)出力:
1
5構造体の配列は独立した値を保持します。インデックスを使って要素を変更すると、その要素だけが変更され、配列をコピーするとすべての値がコピーされます。
struct Score {
var points: Int
}
var round1 = [Score(points: 1), Score(points: 2)]
var round2 = round1
round2[0].points = 50
print(round1[0].points)
print(round2[0].points)出力:
1
50チャレンジ
簡単tryDiscount(_:percent:)を完成させてください。これはPrice構造体を受け取り、割引後のコピーを返します。セント数を割合分だけ減らし、小数点以下は切り捨てます。提供されているコードは元の価格と割引後の価格を出力するため、元の値は変更せずに保持する必要があります。
提供されているコードは、セント単位の価格と、各行に1つずつ割合を読み取り、それぞれについてwas 1000, now 900を出力します。
コードはPrice.swiftとFunctions.swiftに記述します。main.swiftには提供された入力/出力コードが含まれており、編集できません。
自分で試してみよう
// 提供された入出力コード: そのままにしておく
var input: [String] = []
while let line = readLine() { input.append(line) }
let original = Price(cents: Int(input[0])!)
for line in input.dropFirst() {
let cheaper = tryDiscount(original, percent: Int(line)!)
print("was \(original.cents), now \(cheaper.cents)")
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: Swiftプレイグラウンド