（自分用）型を構成する要素　プロパティ

#Swiftの型を構成する要素
Swiftの型は、
クラス、構造体、列挙型として定義できる。
標準ライブラリの型の多くは構造体として定義されている。

構成する要素
-プロパティ
-メソッド
-イニシャライザ
-サブスクリプト
-エクステンション
-ネスト型

#プロパティとは
型に紐付いた値のこと。

本（書籍）に例えると、
本　→　”型”
タイトル、著者名、目次　→　”プロパティ”

#プロパティの分類

###①インスタンスプロパティ（型のインスタンスに紐づくプロパティ）
インスタンスごとに異なる値を持たせることができる。
varキーワードやletキーワードで定義したプロパティは、デフォルトでインスタンスプロパティとなる。

```swift
struct Greeting {
  var to = "Yusei!"  //デフォルトのインスタンスプロパティ
  var body = "Hello!"  //デフォルトのインスタンスプロパティ
}

let greeting1 = Greeting()
var greeting2 = Greeting()

greeting2.to = "Teshima!"

let to1 = greeting1.to //Yusei!
let to2 = greeting2.to //Teshima!

```

###②スタティックプロパティ（型そのものに紐づくプロパティ）
インスタンス間で共通する値の保持などに使用できる。
下記の例では、スタティックプロパティsigntureが共通した値になっている。

```swift

struct Greeting{
   static let signture = "Sent from iPhone."
   var to = "Yusei"
   var body = "Hello!"
}

func print(greeting: Greeting) {
   print("to: \(greeting.to)")
   print("body: \(greeting.body)")
   print("signature: \(Greeting.signature)")
}

let greeting1 = Greeting()
var greeting2 = Greeting()

greeting2.to = "Teshima"
greeting2.body = "Hi!" 

print(greeting:greeting1)
print("--")
print(greeting:greeting2)

//実行結果
to: Yusei
body: Hello!
signature: Sent from iPhone
--
to: Teshima
body: Hi!
signature: Sent from iPhone

```

また、スタティックプロパティは宣言時に必ず値を持たせる必要がある。
値が無い場合、コンパイルエラーとなる。

```swift
struct Greeting {

//値を持っていないためコンパイルエラー
static let signature: String

}

```
###③ストアドプロパティ（値を保持するプロパティ）
変数や定数のように値を代入して保存するプロパティのこと。

###④プロパティオブザーバ（ストアドプロパティの変更の監視）
ストアドプロパティの変更を監視し、変更前と変更後に文を実行するもの。

willSet（変更前に実行）,didSet（変更後に実行）

```swift
struct Greeting {
   var to = "Yusei" {

    //変更前に実行される
    willSet { 
     print("willSet: (to: \(self.to), newValue: \(newValue))")
    }

    //変更後に実行される
    didSet {
     print("didSet: (to: \(self.to))")
    }
  }
}

var greeting = Greeting()
greeting.to = "Teshima"

//実行結果
willSet: (to: Yusei, newValue: Teshima)
didSet: (to: Teshima)

```

###⑤レイジーストアドプロパティ（アクセス時まで初期化を遅延させる）
定義するにはvarキーワードの前に、lazyキーワードを追加する。
※letでは使用不可
レイジーストアドプロパティを利用すると、初期化コストの高いプロパティの初期化をアクセス時まで延ばし、アプリケーションのパフォーマンスを向上させることができる。
例

```swift
struct SomeStruct {
  //初期化した時にログが出力されるようにする
  var value: Int = {
   print("valueの値を生成します")
   return 1
  }()
  
  //アクセスして初めてログが出力される
  lazy var lazyValue: Int = {
   print("lazyValueの値を生成します")
   return 2
  }()
}

var someStruct = SomeStruct()
print("SomeStructをインスタンス化しました")
print("valueの値は\(someStruct.value)です")
print("lazyValueの値は\(someStruct.lazyValue)です")

//実行結果
valueの値を生成します
SomeStructをインスタンス化しました
valueの値は1です
lazyValueの値を生成します
lazyValueの値は2です

```

###⑥コンピューテッドプロパティ（値を保持せずに算出する）

プロパティ自身では値を保存せず、すでに存在するストアドプロパティなどから計算して値を返すプロパティ。
アクセスごとに値を計算し直すため、計算元の値との整合性が常に保たれるという性質がある。

{}内にget（ゲッタ）キーワード、set（セット）キーワードを入れて定義する。

####ゲッタ（get）　値の返却
例

```swift
struct Greeting {
   var to = "Yusei"
   var body: String {
     get {
       return "Hello, \(to)!"  //ストアドプロパティtoを利用可能
       }
    }
}

let greeting = Greeting()
greeting.body   //Hello,Yusei!

```

####セッタ（set）　値の更新
例　温度表記の切り替え

```swift
struct Temperature {
   //摂氏温度
   var celsius: Double = 0.0
   
   //華氏温度
   var fahrenheit: Double {
     get { 
         return (9.0 / 5.0) * celsius + 32.0
        }
     set {
         celsius = (5.0 / 9.0) * (newValue - 32.0)
        }
   }
}

var temperature = Temperature()
temperature.celsius  // 0
temperature.fahrenheit  //32

temperature.celsius = 20
temperature.celsius  //20
temperature.fahrenheit  //68

temperature.fahrenheit = 32
temperature.celsius  //0
temperature.fahrenheit  //32

```