-
Notifications
You must be signed in to change notification settings - Fork 0
Swift_struct
実はオブジェクトじゃない。データを扱うための存在。
C言語でも出てきましたね。あれです。
ただ、Swift の構造体はメソッドも書けます。イニシャライザも書けます。
クラスと全く一緒に見えます。つーかほとんど一緒です。
struct User {
// プロパティ
var name: String
var age: Int
//イニシャライザ
init(name: String, age: Int) {
self.name = name
self.age = age
}
// メソッド
func greet() {
print("こんにちは。私は\(self.name)です。\(self.age)才です。")
}
}
let user = User(name: "小林", age: 20)
user.greet() // こんにちは。私は小林です。20才です。一緒過ぎて、クラスとの違いを話すほうが楽です。
例えば以下のような、名前のプロパティを持つ Person クラスと、Person をプロパティとして持つ House クラスを用意します。
class Person {
var name: String
init(name: String) {
self.name = name
}
}
class House {
var person: Person
init(person: Person) {
self.person = person
}
func call() {
print("\(self.person.name)の家へようこそ")
}
}これを、以下のように使ってみましょう
let person = Person(name: "小林")
let kobayashiHouse = House(person: person)
kobayashiHouse.call() // 小林の家へようこそ問題なさそうですね。しかしこうするとおかしなことになります。
let person = Person(name: "小林")
let kobayashiHouse = House(person: person)
kobayashiHouse.call() // 小林の家へようこそ
person.name = "佐藤"
kobayashiHouse.call() // 佐藤の家へようこそなんと、後から person の値を変更すると House に渡した person の値も変更されてしまいました。
つまりクラスは、値を渡しているのではなく、値の参照先 を渡しているということです。
同じところに参照しているので、一つを変えると全部変わってしまいます。
さて、Person クラスを構造体にしてみましょう。
struct Person {
var name: String
init(name: String) {
self.name = name
}
}
class House {
var person: Person
init(person: Person) {
self.person = person
}
func call() {
print("\(self.person.name)の家へようこそ")
}
}同じように使ってみても、値が変更されないことがわかります。
let person = Person(name: "小林")
let kobayashiHouse = House(person: person)
kobayashiHouse.call() // 小林の家へようこそ
person.name = "佐藤"
kobayashiHouse.call() // 小林の家へようこそ
print(person.name) // 佐藤もちろん、person の name プロパティは変わっていますが、クラスに渡した name プロパティは変わっていません。
これは構造体が渡されるとき、値がコピーされるからということになります。
もっと言えば、構造体が渡されるときは、写真を撮るようにその状態が渡されるというわけです。
その後どういじくられても写真のデータは変わらないように、構造体で渡したデータは変わることがありません。
構造体は継承ができません。プロトコルは使えます。
とにかく、データが変わらなくて嬉しいことから、データを扱うクラスの場合は構造体で書いたりすることがよくあります。
まあ、あまり気し過ぎる必要はありません。とりあえず構造体ってのがあって、クラスっぽいよってことがわかっていれば今は OK です。
これはのちに 破壊的メソッドと非破壊的メソッド、そして immutable で詳しく話します。
- クラスとほぼ一緒、だけど値がコピーされるから渡された後に変わることがない
- その性質を活かして、データを扱うクラスを構造体で書くことがある
- 今はクラスとの使い分けで悩まないで良い。とりあえずクラス使っとけ。
- 気が向いたら 破壊的メソッドと非破壊的メソッド、そして immutable を読んで欲しい