Swiftでのクラスとstruct(構造体)の使い分けを解説します

クラスはオブジェクト指向においての超基本概念で、クラスからオブジェクトが作られます。そしてこのクラスと良く似た概念がstructで、この二つがどう違うのかよくわからないという声もたびたび耳にします。

そこでこのページでは、クラスとstructがどう違うのか、どのように使い分ければ良いのか、といったことを解説します。

structとは

structの基本的な使い方はクラスと同じで、structを元にオブジェクトが作られます。サンプルコードは以下です。

struct 構造体名 {
    var num1:Int;
    var num2:Int = 100;
    var str:String;
    init(value: Int) {
        val = 150
    }
}

宣言の仕方はクラスとほぼ同じですが、継承ができない、値渡しである、といった違いがあります。クラスは参照型ですが、structは値渡しです。

structのコード

structの基本的なコードを紹介します。まず初期値なしのバージョンです。

//structの定義
struct FruitPrice {
    var apple:Int;
    var orange:Int;
    var melon:Int;
    var pineapple:Int;
    var banana:Int;
}

//インスタンスを作成して初期値を指定する
var price = FruitPrice(apple: 100, orange: 150, melon: 700, pineapple: 450, banana: 200)

print("apple : \(price.apple)")
print("orange : \(price.orange)")
print("melon : \(price.melon)")
print("pineapple : \(price.pineapple)")
print("banana : \(price.banana)")

このコードを実行すると以下のように出力されます。

apple : 100
orange : 150
melon : 700
pineapple : 450
banana : 200

初期値がある場合コードは以下のようになります。

//structの定義
struct FruitPrice {
    var apple:Int = 100;
    var orange:Int = 150;
    var melon:Int = 700;
    var pineapple:Int = 450;
    var banana:Int = 200;
}

//インスタンスを作成
var price = FruitPrice();

print("apple : \(price.apple)")
print("orange : \(price.orange)")
print("melon : \(price.melon)")
print("pineapple : \(price.pineapple)")
print("banana : \(price.banana)")

このコードを実行すると以下のようにコンソール出力されます。

apple : 100
orange : 150
melon : 700
pineapple : 450
banana : 200

イニシャライザを定義すると以下のようになります。

//structの定義
struct Area {
    var radius: Int // 半径
    var pi: Double // 円周率
    // イニシャライザ
    init(radius: Int, pi: Double) {
        self.radius = radius
        self.pi = pi
    }
}

//インスタンスを作成
var val = Area(radius:100, pi: 3.1415927)

上記のコードを実行すると以下のように出力されます。

radius : 100
pi : 3.1415927

クラスとstructはどう使い分けるべきか

structのサンプルコードは上記の通りですが、結局どのようにクラスと使い分ければ良いのでしょうか。基準は大きく分けると二つあって、まず継承したいかどうかです。継承したいならクラスでないと継承できないので、その場合クラス一択になります。

次に、値渡しか参照渡しかによります。structは値渡しなので、structのなかの変数を直接書き換えることはできません。参照渡しでク宣言部分の値を書き換えたいならクラスを選択することになります。

これらをまとめてひとことでシンプルにまとめると、structの方がより簡易的です。どこが簡易的なのかは上記の通りですが、イメージ的に言えば作りこむならクラス、簡易的な記述で問題ないならstructといった考え方で良いかと思います。

一応詳細な比較をしておくと以下のようになります。

・継承
参照型◯
値型×

・プロトコル実装
参照型◯
値型◯

・拡張
参照型◯
値型◯

・プロパティ(格納型)
参照型◯
値型◯

・プロパティ(算出型)
参照型◯
値型◯

・タイププロパティ(格納型)
参照型×
値型◯

・タイププロパティ(算出型)
参照型◯
値型◯

・メソッド
参照型◯
値型◯

・タイプメソッド
参照型◯
値型◯

クラスとstructのコード比較

次にクラスとstructで同じコードを書いて比較してみます。

var someValue1 = SomeValue(value:20)
var someValue2 = someValue1
someValue2.setNewValue(value:21)
// Class (someValue1, someValue2どちらも変わる)
// someValue1.value = 21
// someValue2.value = 21

// Struct (someValue1の値は変化しない)
// someValue1.value = 20
// someValue2.value = 21

クラスではSomeValueで値が変化しましたが、structでは値が変化していません。また以下のサンプルコードではstructだけ外部からの値変更に対してエラーが出ています。

class Something {
    var mutableValue = 10
}
let immutableClass = Something()
// Cannot assign to value: 'immutableClass' is a 'let' constant エラー
// immutableClass = Something()
immutableClass.mutableValue = 20
// immutableClass.mutableValue => 20

struct SomeStructure {
    var immutableValue = 10
}

let immutableStruct = SomeStructure()

// immutableStruct = SomeStructure()
// Cannot assign to value: 'immutableClass' is a 'let' constant エラー

// immutableStruct.immutableValue = 20
// Cannot assign to property: 'immutableStruct' is a 'let' constant エラー

まとめ

以上、クラスとstructの違いについて解説してきました。

すべてstructで実装することは難しいですが、逆にすべてクラスで実装することは可能です。

しかしstructを使った方が便利な面もあるため、上で紹介したような使い分けがおすすめです。

▼Swift関連の記事一覧
1, 【Swiftのフリーランス案件情報付き】仕事やエンジニアの将来性・学習方法!
2, 繰り返し処理に使えるSwiftのfor文とfor-in文の便利な使い方まとめ
3, 条件分岐に便利なSwiftのSwitch文の使い方まとめ
4, アプリ開発でよく使うSwiftの4つの文法を解説します
5, Swiftのoptional型を使いこなすための7つのポイント
6, Swiftで文字列を扱うためのstring型の使い方
7, Swiftでの配列の宣言・初期化・代入・参照の方法まとめ
8, 実際の開発現場でのSwiftの変数・定数の使われ方を解説します
9, Swiftでif let文を使って出来ることとguard letの使い分けに関して
10, 開発現場でよく使うSwiftのif文の条件分岐をまとめました
11, SwiftにおけるTupleの使い方とわかりやすく解説します
12, 初心者にオススメのSwiftのサンプルコードをまとめてみました
13, SwiftのString、Int、Doubleの型の変換方法をまとめました
14, 開発現場で役に立つSwiftのクロージャの使い方
15, Swiftでwhileを使って上手に繰り返し処理を行おう
16, Swiftで文字列の長さをチェックするのにlengthを使ってみよう
17, Swiftのdictionaryの使い方と初期化方法をまとめました
18, Swiftの値渡しと参照渡しに関するまとめ
19, Swiftで参照渡ししたい時のinoutの便利な使い方
20, Swiftでfor-in文でindexを使いたい時の方法まとめ
21,(この記事)Swiftでのクラスとstruct(構造体)の使い分けを解説します

人気記事

編集部おすすめ記事

この記事を読んだ人はこんな記事を読んでいます