【Swift】構造体の使い方。複数データを1つの変数で管理する入れ物。(Swift 2.1、XCode 7.2)

2020年6月16日

構造体とは

構造体とは、配列や辞書と同じように複数のデータを1つの変数で管理できる入れ物である。関数を定義することができるので、管理しているデータを使って用途に応じた様々な処理を実装することができる。

構造体は以下のように定義する。

 

構造体と辞書の使い分け

辞書を使うより構造体を使った方が良い例を見てみよう。

例えば、重さ「10kg」、産地「茨城」、通常価格「3000円」、賞味期限(商品によって異なる)の米袋3個を変数で作る場合について考える。賞味期限は変数を作ったあとに設定するものとする。

辞書を使う場合は以下のようなコードになる。商品の変数を作るたびに重さ、産地、通常価格を設定しなければならないのが冗長だ。変数をコピーして作ればいいという指摘があるかも知れないが置いておく。

 

構造体を使うと以下のようになる。Rice()と書くだけで重さ、産地、通常価格が設定された変数を作ることができた。このように、データの詰め合わせ内容があらかじめ決まっているようなときは構造体を使うのが便利である。

 

構造体に関数を持たせる

構造体の中にイニシャライザ(初期化メソッド)を定義すれば、構造体が呼び出されたときの初期化処理を実装することができる。

例えば、上記コードでは変数を作ったあとに賞味期限を設定したが、下記コードのようにイニシャライザを定義しておくと、変数を作るときの引数で賞味期限を設定できるようになる。

 

ちなみに以下のコードのように、構造体を呼び出すときにすべてのプロパティの値を引数に与えれば、イニシャライザを定義していなくても変数を設定できる。

 

以下のコードは、構造体の中に賞味期限のチェックをする関数を定義した例。このような格納データを使ったチェック処理や頻繁に利用する計算は構造体の中に関数として定義しておくと便利だ。

構造体とクラスの使い分け

構造体の仕様はクラスと良く似ているので、構造体とクラスの違いと使い分けについて疑問を持つ人が多い。大きな違いは「構造体は値型、クラスは参照型」ということである。

値型は、変数の保存先にデータそのものを保持し、別の変数に代入するときは値のコピーが作られる仕様である。例えば、下図の変数Aを変数Bに代入した場合、変数Aでweightの値を20に変更したあとに、変数Bのweightを確認しても10のままになる。

値型の例

 

一方、参照型は変数の保存先にデータの参照先を保持し、別の変数に代入するときは参照先のコピーが作られる仕様である。変数A、変数Bは同じデータを見ているので、例えば、変数Aでweightの値を20に変更したあとに、変数Bのweightを確認すると20になる。

参照型

 

クラスは参照型だが、自身をコピーして返す関数を持たせることで値型のような振るまいをさせることができるので、どちらを使うか迷うときはクラスを使えば良い。

そうなると構造体の存在意義が微妙になるが、設計者の視点で考えると、クラスを設計するときは新たな設計書、テスト仕様書を作ることになるので、構造体を設計するよりも大掛かりになるイメージがある。

一方、構造体はクラス内の1つの変数として設計するので軽いイメージがある。なので、参照型にする必要が無いのであれば、まとめる変数の数が少ないときは構造体を使ったほうがレビューする人にとっても有難いことになる。