5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SwiftでClassだけでなくStructも積極的に使う方がコードの可読性が上がる話 その1

Last updated at Posted at 2019-01-20

はじめに

Qiita初投稿になります。2018年1月からプログラミングの学習を開始し、今までPython, Swift, Rubyを触ってきました。エンジニアとしてスキルアップしていくためにも、各言語の仕様を理解したコードがかけるようになりたいと考えていますのでアドバイス等いただけると嬉しいです。

この記事の目的・背景

今までプライベートiOSアプリを開発していたが、Class以外にStructやEnumを積極的に使ってこなかったのでclass、struct、enumの比較とそれぞれどのような場面で使用できるかまとめてみます。今回はClassとStructの比較を主に書いてみます。

ClassとStructの大きな違い

まず始めに、SwiftのClassとStructの大きな違いをおさらいしてみます。
・Classは継承可能だが、Structはできない
・Classインスタンスは参照型、Structは値型

SomeValue.swift
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

letによるMutabilityが異なる

Mutability.swift
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 エラー

let で定義すると、 Classのインスタンスはimmutableになりますが、プロパティはmutableのままになっています。一方、Structはデータをカプセル化して保持する役割がありますので、そのまま外部から値を変更しようとするとエラーになります。

Struct内で定義したプロパティの値を変更するには、メソッドの前に mutating をつける

Struct内のプロパティの値を変更する際は、mutating をメソッドの先頭につけることでプロパティの値を変更することが可能になります。

changePropertyInStruct.swift
struct SomeStructure {
    var value:Int
    
    init(value:Int) {
        self.value = value
    }
    
    mutating func addOne(){
        self.value += 1
    }  
// 下記のように、mutatingをつけないと、Left side of mutating operator isn't mutable: 'self' is immutable というえらエラーが発生する
//    func addTwo(){
//        self.value += 2
//    }
}

var something = SomeStructure(value: 1)
something.addOne()
// something.value => 2

Structを使うメリット

  1. クラスのように簡単に使える
  2. クラスファイルが増えすぎない
  3. データ自体に関する処理を任せることで構造がわかりやすくなる

・クラスのように簡単に使える
クラスを定義するときと同様にイニシャライザも使え、プロパティやメソッドの定義も簡単!

・クラスファイルが増えすぎない
クラス毎にファイルを分ける必要がなくなり、データに関する処理をStructファイルでまとめてしまったり、Controllerファイルに記載しても良いので他のクラスファイルと分離して管理することができます。

・データ自体に関する処理を任せることで構造がわかりやすくなる
スクリーンショット 2019-01-20 23.44.43.png
図の様にコントローラーファイル、モデルファイル、Structファイルを用意し、それぞれ適切な役割(例えばStructに全てデータに関する変数と処理を書く)を与えることでコードの可読性が上がり、チームで開発する際に新規メンバーのキャッチアップも早くなりそうです。

まとめ

Structはクラスの様に書くことができ、データを保持し、データの処理を行う関数をまとめるのに適しています。しかしながら、継承が存在せず、Struct単体では不便な点もあります。サブクラスのようなものを作成したい時には、Enumも同時に利用することで同様の機能を実装可能ですので、次回はEnumも利用したコードの可読性をあげる方法を考えてみようと思います。

最後まで読んでいただき、ありがとうございました!不明な点や間違いがありましたらコメントしていただけると嬉しいです〜!

5
5
0

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
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?