swift の可変値と不変値 #cocoa_kansai

80
EZ-NET 熊谷友宏 http://ez-net.jp/ 2015.02.28 @ 第60回 Cocoa 勉強会関西 Swift カジュアルプログラミング 《基礎》不変値と可変値

Upload: tomohiro-kumagai

Post on 15-Jul-2015

1.305 views

Category:

Technology


0 download

TRANSCRIPT

EZ-NET 熊谷友宏 http://ez-net.jp/

2015.02.28 @ 第60回 Cocoa 勉強会関西

Swift カジュアルプログラミング

《基礎》不変値と可変値

熊谷友宏http://ez-net.jp/ @es_kumagai

Xcode 5 徹底解説

IP Phone 音でダイヤル 音で再配達ゴッド

いつもの電卓 for iPhone

いつもの電卓 for iPad

音で再配達

熊谷友宏http://ez-net.jp/ @es_kumagai

#yidev横浜 iPhone 開発者勉強会

開催中

不変値と可変値Swift にある変数のお話

Swift には2つの変数 があります

不変値変数

// 値を書き込んだら… let value = 10

// 変更はできない value = 20

▶ let で宣言された変数 ▶ 値を書き込めるのは1度だけ

Swift

可変値変数

// 値を書き込んで… var value = 10

// さらに書き換えが可能 value = 20

▶ var で宣言された変数 ▶ 何度でも書き換え可能

Swift

原則可能な限り let を使う

let prices = [100.0, 300.0, 200.0] let withTax = { $0 * 1.08 } let pricesWithTax = prices.map(withTax)

let sum = pricesWithTax.reduce(0) {$0+$1}

Swift

➡ Swift らしい安全なコードになる

おしまい?

今回はもう少し先のお話

目標

▶ 変数を値と状態で捉える ▶ 変数から Swift の全容を探る

目標

変数・構造体・クラスを知るとSwift はもっと楽しくなる

不変値と可変値役割と性質

不変値

役割▶ 値を表現する

不変値

値とは▶ 評価したい式で使うもの ▶ 何かの式を評価したもの

用途▶ 引数 ▶ 結果

不変値

a = f(x,y,z)

不変値

▶ 引数は使う前に決まる ▶ 結果は決まったら変わらない

評価式と値

もし変わってしまったら?

不変値

りんごは 130 円です

じゃあ、3 つください

_φ(・_・

全部で 500 円です!え? りんごっていくらだっけ

りんごは 250 円ですあれ?

そうだメモで確かめよう ほんとだ 250 円って書いてあった

???

▶ りんご = 130▶ 値段メモ.りんご = りんご

▶ 購入数 = 3▶ print 金額(りんご,購入数) 500

▶ print (りんご) 250▶ print (値段メモ.りんご) 250

不変値

変更の余地があると▶ 変更を考慮したコードを記述渡し手と受け手で意思共有も必要

▶ 取得値が勝手に変わる可能性コピーするかの判断が常に必要

煩わされる▶ そもそも変える必要性がない

値の扱いに優れた変数不変値変数 let の誕生

特徴▶ 設定したら書き変わらない ▶ 常にコピー

利点▶ 変化に備えた考慮が不要 ▶ コピーするかどうかで悩まない

不変値変数 let

使い方

不変値変数 let

三項演算子 “?:” を使いましょう

不変値変数 let

条件で値を変えたい

三項演算子による値の設定

let discountRate = (isBargainDay ? 0.03 : 0.00)

Swift

クロージャーを活用しましょう

不変値変数 let

複雑な条件で値を変えたい

クロージャーによる値の設定

let getPrice = { () -> Double? in if inStock {

return applyRate(basePrice) } else {

return nil }

}

let price = getPrice()

Swift

従来通りの即時初期化をオススメ

不変値変数 let

Swift 1.2 なら遅延初期化も可能

遅延初期化による値の設定

let price:Double?

if inStock {

price = applyRate(basePrice) } else {

price = nil }

Swift

Swift 1.2

コードを読まないと値の設定場所が分からない…

即時初期化の利点

let basePrice = 150 let discountRate

= (isBargainDay ? 0.03 : 0.00)

let price = getPrice()

Swift

▶ 傍を見れば設定値が分かる ▶ どんな場合も初期化できる、はず

可変値

役割▶ 状態を表現する

可変値

状態とは▶ 時間軸で変化する値 ▶ 今の有り様を表現するもの

用途▶ プロパティ ▶ バッファー

可変値

可変値

▶ 時事刻々と変化する ▶ 状況に応じて調整可能

移動する物の位置

location: (x,y)

カップの容量

capacity: ㎖

可変値

変化する前提があると▶ 変更を常に意識できる渡し手と受け手で意思が伝わる

▶ 再取得時には変わっている可能性コピーが必要

扱い方が定まる▶ 扱いに悩む必要がなくなる

状態の扱いに優れた変数可変値変数 var の登場

特徴▶ 設定後に書き換えられる ▶ 常にコピー

利点▶ 変化を前提とした扱いが可能 ▶ コピーするかどうかで悩まない

可変値変数 var

2種類の変数の誕生

2種類の変数

▶ コーディングの方針が定まる ▶ ソースコードの可読性が向上

宣言 内容 用途let 不変値 値var 可変値 状態

変数には用途を込められる

2種類の変数が誕生したからには言語によるサポートがある

変数の言語サポート

▶ 値と状態の相互運用 ▶ 変数に特化したオブジェクト

値と状態の相互運用

変数のコピー

変数はコピーされる▶ 代入時に内容をコピー ▶ 他からの干渉を防ぐのが目的

コピー後の性質は代入先に依る▶ 可変値に不変値を入れれば変更可 ▶ 元の性質には束縛されない

値と状態の相乗りを実現変数のコピーで

相互乗り入れのイメージ

この星は移動するよ!

今は (0, 0) に居るよ今はどこに居るの?

_φ(・_・横に20、縦に800、移動して!

移動したよ!

状態を可変値で宣言

今の状態を値にコピーして返却

状態の変更を不変値で指示

受け取った値を不変値にコピー

受け取った値をコピーして状態を更新

今は (20, 800) に居るよ

今はどこに居るの?

_φ(・_・

移動したよ!

前回より横に60移動したのね!

今は (80, 800) に居るよ

勝手に移動したよ!

お、今はどこに居るの?

_φ(・_・

受け取った値を不変値にコピー

受け取った値を不変値にコピー

今の状態を値にコピーして返却

今の状態を値にコピーして返却

受け取った値と以前にコピーした値を比較

なんらかの値で状態を更新

変数に特化したオブジェクト

構造体

おさらい

Swift の変数は2種類

▶ 決まれば変わらない値 ▶ 時事刻々と変化する状態

Objective-C は1種類の変数で工夫

▶ Immutable クラス ▶ Mutable クラス

Immutable クラス

▶ 初期化後の状態変化を禁止 ▶ 不変値に類似

Mutable クラス

▶ 初期化後の状態変化を制限しない ▶ 可変値に類似

Objective-C ではクラス設計によって変数を制御

プログラマーの自主性に依存

Swift では言語仕様が主導権を握る

コンパイラによる変数の統制

変数の種類で制御オブジェクトの性質が格納先で変化

▶ Immutable 扱い

可変値変数▶ Mutable 扱い

変数の種類で制御

不変値変数

変数の種類で振る舞いを変える

変数の種類で制御

構造体の登場

▶ 内容を自由に設計できる ▶ 内容は別変数へ代入時にコピー ▶ 格納先に応じて振る舞いを制御

目的

構造体

値や状態を表現するオブジェクト

特徴

値や状態で使うオブジェクトは

構造体

原則、構造体で定義

▶ String ▶ Array ▶ Int

構造体

定義方法

▶ 内容は可変値変数のプロパティで定義 ▶ 構造体を可変値で扱う時のみ変更可

内容の定義

構造体

struct MyValue {

var state:Int = 10 }

▶ mutating な機能のみ内容を変更可能 ▶ mutating な機能は可変値でのみ利用可 ▶ それ以外の機能は常に利用可能

機能の定義

構造体

struct MyValue {

mutating func mutableMethod(v:Int) func immutableMethod(v:Int)

}

▶ 内容は常に変更可能 ▶ デイニシャライザは存在しない

イニシャライザの定義

構造体

struct MyValue {

init() }

▶ 値や状態に特化したオブジェクト ▶ Immutable な振る舞いが基本 ▶ Mutable な機能は明示定義状態変化を伴う機能か見て分かる

▶ 使用中でも不変性を振替可能コピーするので元の値に干渉しない

まとめ

構造体

構造体

オブジェクト設計におけるプログラマーへの負担が激減

クラスは?

▶ 状態を制御する機能の集合体 ▶ 内部に状態を持つ

目的

クラス

状態を制御するオブジェクト

特徴

UI の制御など

クラス

制御機能の設計時に使用

▶ 制御する状態は共有 ▶ 代入時は実体がコピーされる状態はコピーされない

▶ 不変値変数は実体の不変性を保証状態の不変性は保証しない

状態は共有する

クラス

クラス

状態

実体

制御

実体複製

制御

▶ 同じ状態の新しい実体を作成状態もコピーしたい

クラス

▶ Immutable クラスを自身で設計状態の不変性を保証したい

▶ コンセプト的に無理(状態制御が目的)不変値のときに Immutable にしたい

性質を踏まえた扱い方

クラス

そもそもクラス?

▶ 実体をコピーするときに状態もコピーする必要性が生じた

▶ 状態の不変性を保証が必要になった

構造体での実装も検討するそんなときは

クラス

定義方法

▶ 状態は可変値変数のプロパティで定義 ▶ 実体を不変値で扱う時でも変更可

状態の定義

クラス

class MyValue {

var state:Int = 10 }

▶ 機能内から状態を変更可能 ▶ 変数の種類を問わず利用可能

機能の定義

クラス

class MyValue {

func method(v:Int) }

▶ 状態は常に変更可能 ▶ デイニシャライザでの後始末が可能

イニシャライザの定義

クラス

class MyValue {

init() deinit

}

▶ 機能に特化したオブジェクト ▶ 状態を共有して制御する実体を複製して共通の状態を制御可能

▶ 不変性が保証するのは実体だけ状態操作できないクラスは無価値

まとめ

クラス

総括

総括

変数・構造体・クラスを知るとSwift はもっと楽しくなる

総括

2種類の変数▶ 不変値変数 let で値を扱う ▶ 可変値変数 var で状態を扱う

構造体▶ 値や状態に特化したオブジェクト ▶ 変数の種類で状態の不変性を制御

クラス▶ 状態の制御に特化したオブジェクト