Edited at

Swift さくっと確認したい基礎文法 [Struct(構造体)]

More than 3 years have passed since last update.


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


クラスが参照型であるのに対して構造体は値型ってどういうこと?

参照型であるクラスは

複数の変数に代入されても、一つのオブジェクトを共有しているので

いずれかの変数の値が変更されれば、他の変数にもそれが反映される。

一方で、

値型である構造体は、

複数の変数に代入された場合、新しい構造体として代入されるので、

いずれかの変数が変更されても他の変数にその変更は影響しない。

言葉で説明しても分かりづらいので、

下記の例を見れば理解できると思います。


swift


// 構造体(値型)
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"



関数を定義する

こちらもクラスと同様に関数を定義できます。

インスタンスを作成した後、関数を呼び出します。


swift

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(構造体)のプロパティを変更する

構造体は基本的にはメソッド内で、

自分自身のプロパティの値を変更することはできません。

以下のコードはエラーになります。


swift

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を付けます。


swift

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ついて