Struct[構造体]とは?
ひとことで簡単に言えば、継承のできないクラス。
- 複数の値を1個のオブジェクトで管理できる。
- 辞書とは違い、同じ構造のオブジェクトを複製することができる。
- クラスとは違い、継承はできない。
- クラスが参照型であるのに対して構造体は値型
- イニシャライズも関数も使える。
使いどころ
汎用的に使いたいので、クラス化したい!
ただ、継承は必要ない。
というときに使う。
と理解しているつもりですが、
間違っている等のご意見があれば優しくご指摘をお願いします。
基本的な書き方
基本的な書き方はクラスと同様。
struct 名前 {
var hogehoge:型
var hugahuga:型
let weiwei:型
}
初期値なしでも、ありでも書くことができる。
インスタンスを作る際は
下記のvar iPhone5 = IPhone5()
ように基本的にはクラスと同様に書く。
※初期値がないStructの場合は、インスタンス作成時に初期値を設定する必要がある。
// 初期値なし
struct SmartPhone {
var os:String
var version:Double
var width:Int
var height:Int
}
// 初期値あり
struct IPhone5 {
var os:String = "iOS"
var version:Double = 7.0
var width:Int = 320
var hight:Int = 568
}
// 初期値なしの場合、インスタンス作成時に初期値を入れる。
var iPhone6 = SmartPhone(os: "iOS", version: 8.3, width: 375, height: 667)
println(iPhone6.width) // 375
// 初期値ありの場合、そのままインスタンス化
var iPhone5 = IPhone5()
println(iPhone5.width) // 320
イニシャライザを定義する
Structでは、クラスと同様にイニシャライザを定義できます。
書き方は同じです。
下記の例では、widthとheightの合計値によって
sizeの初期値を決めています。
struct Box {
let width:Int
let height:Int
let size:String
init(width:Int, height:Int){
self.width = width
self.height = height
var sumSize = width+height
switch (sumSize) {
case 0...100:
size = "S"
case 101...200:
size = "M"
case 201...300:
size = "L"
default:
size = "Free"
}
}
}
// Bozをインスタンス化(initメソッドを呼ぶ)
var newBox = Box(width: 100, height: 30)
println(newBox.size) // M
クラスが参照型であるのに対して構造体は値型ってどういうこと?
参照型であるクラスは
複数の変数に代入されても、一つのオブジェクトを共有しているので
いずれかの変数の値が変更されれば、他の変数にもそれが反映される。
一方で、
値型である構造体は、
複数の変数に代入された場合、新しい構造体として代入されるので、
いずれかの変数が変更されても他の変数にその変更は影響しない。
言葉で説明しても分かりづらいので、
下記の例を見れば理解できると思います。
// 構造体(値型)
struct CardStruct {
var color:String
}
// クラス(参照型)
class CardClass {
var color:String
init(color:String){
self.color = color
}
}
var cardStruct1 = CardStruct(color: "black")
var cardStruct2 = cardStruct1
cardStruct2.color = "red"
println("cardStruct1:\(cardStruct1.color)、cardStruct2:\(cardStruct2.color)")
var cardClass1 = CardClass(color: "black")
var cardClass2 = cardClass1
cardClass2.color = "red"
println("cardClass1:\(cardClass1.color)、cardClass2:\(cardClass2.color)")
// 構造体:cardStruct2.colorを変更してもcardStruct1.colorはそのまま
"cardStruct1:black、cardStruct2:red"
// クラス:cardClass2.colorが変更されるとcardClass1.colorも変更される。
"cardClass1:red、cardClass2:red"
関数を定義する
こちらもクラスと同様に関数を定義できます。
インスタンスを作成した後、関数を呼び出します。
struct Card {
var width:Int
var height:Int
func getSquare() -> Int {
return width*height
}
}
var card = Card(width: 100, height: 150)
println(card.getSquare())
Struct(構造体)のプロパティを変更する
構造体は基本的にはメソッド内で、
自分自身のプロパティの値を変更することはできません。
以下のコードはエラーになります。
struct Card {
var width:Int
var height:Int
func getSquare() -> Int {
// エラー(メソッド内でプロパティを変更できない。)
self.width = 300
return width*height
}
}
var card = Card(width: 100, height: 150)
println(card.getSquare())
プロパティを変更する場合は、
変更するメソッドにmutating
を付けます。
struct Card {
var width:Int
var height:Int
mutating func getSquare() -> Int {
self.width = 300
return width*height
}
}
var card = Card(width: 100, height: 150)
println(card.getSquare())
※追加予定
structにおけるsubscriptついて