Menu
Coddy logo textTech

値セマンティクス

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
challenge icon

チャレンジ

簡単

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)")
}
quiz icon腕試し

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

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

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