型の構成要素

Swiftの型には、

  • クラス
  • 構造体(struct)
  • 列挙型(enum

の3種類がある。標準ライブラリの型の多くはstructで実装されている。

型に共通する要素

  • 型が持つ値を保存するプロパティ(型に紐づく変数や定数)
  • 振る舞いを示すメソッド(型に紐づく関数)
  • 初期化を行うイニシャライザ
  • コレクションの要素を取得するサブスクリプト
  • 型の中に型を定義するネスト型

定義方法

struct User {
}

class User {
}

enum User {
}

インスタンス化の方法

型名()でインスタントを生成する。()の中には、必要に応じて引数を渡す。クラスと構造体はデフォルトのイニシャライザを持つので、引数なしで初期化できる。列挙型はデフォルトのイニシャライザを持たないので()だけではインスタンスにできない。ケースを指定して、生成する。

struct structUser {}
class classUser {}

let structUser = structUset()
let classUser = classUset()

プロパティの定義方法

struct User {
 var name: String = "Murata" // var name = "Murata"でもいい。再代入できる。
 let age: Int = 12 // 再代入不可能
}

let user = User()
print(user.name) // "Murata"
print(user.age) // 12

プロパティの型の整合性を保つためにインスタンス化が完了するまでに、全てのプロパティに値が代入されている必要がある。ゆえに宣言時に初期値を持っているか、イニシャライザの処理の中で初期化されるかのいずれかの方法が必要である。

プロパティの種類

  • インスタンスプロパティ・・・型のインスタンスに紐づく。宣言時に初期化かイニシャライザで初期化を行う。
  • スタティックプロパティ・・・型自身に紐づく。イニシャライザによる初期化のタイミングがないので、宣言時に必ず値を代入する必要がある。
  • ストアドプロパティ・・・値を保持するプロパティ。letやvarで定義する。
  • コンピューテッドプロパティ・・・プロパティ自身では値を持たずストアドプロパティなどから計算して値を返す。セッターとゲッターを使う。ゲッターは必須である。

コンピューテッドプロパティの例

struct Square {
 let width = 10
 let height = 20

 var area: Int {
    get {
      return width * height
    }
 }
}

let square = Square()
print(square.area)

※プロパティオブザーバ

ストアドプロパティの変更の監視をする。変更前と変更後に実行される。willSet didSetで実行する。

struct User {

 var name = "murata" {
    willSet {
      print("No change")
    }
    didSet {
      print("it was changed")
    }
 }
}

var user = User()
user.name = "abe"

=> No change
=> it was changed

エクステンション

既存の型にコンピューテッドプロパティやメソッド、イニシャライザを追加できる。

//メソッドの追加
extension String {
   func printSelf() {
      print(self)
   }
}

let text = "abc"
text.printSelf() => abc


//コンピューテッドプロパティの追加
extension String {
   var enclosedSelf: String { return "『\(self)』" }
   func printSelf() {
      print(self.enclosedSelf)
   }
}

let text = "abc"
text.printSelf() => 『abc』

//イニシャライザの追加
struct Book {
    let id: String
    let title: String
    var price: Int
}

extension Book {
    init() {
        id = "000"
        title = "タイトルなし"
        price = 0
    }
}

let book1 = Book(id: "001", title: "SwiftyBook", price: 1500)
print(book1.title) => SwiftyBook
let book2 = Book()
print(book2.title) => タイトルなし