LoginSignup
180

More than 5 years have passed since last update.

posted at

updated at

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

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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
180