>100 Views
June 08, 15
スライド概要
2015.06.06 に開催した『第0回 カジュアル Swift プログラミング勉強会』で発表したスライドです。
勉強会が第0回ということと、Swift が1周年を迎えたことから、今に改めて振り返ってみると何か発見があったりするのかなと思って、簡単ながらこんなスライドにまとめてみました。
※ Docswell での公開に移行する直前の Slideshare での閲覧数は 2,075 でした。
正統派趣味人プログラマー。プログラミングとは幼馴染です。
Swift を振り返ってみよう 2015.06.06 カジュアル Swift プログラミング #0 EZ-‐‑‒NET 熊⾕谷友宏 http://ez-‐‑‒net.jp/
Swift 楽しい!
熊谷友宏 http://ez-net.jp/ @es̲kumagai Xcode 5 徹底解説 MOSA IP Phone 音でダイヤル いつもの電卓 with 割勘ウォッチ 音で再配達ゴッド
新言語 Swift 登場 2014.06.02 @ WWDC 2014
特徴 1. Fast 動的言語らしさをなくして高速化 2. Modern 親しみやすい言語設計 3. Safe 不測の事態を招かない言語設計 4. Interactive コンパイル言語でありながら即時実行が可能
コンセプト Objective-C without the C ― C 言語構造からの訣別 ―
新しい概念 1. Closures 関数を柔軟に扱う 2. Type inference 型推論で効率良くコーディング 3. Multiple return types 戻り値で複数の値を返せる 4. Generics 型に縛られない実装 5. Namespaces モジュール単位での名前空間
互換性 1. Interoperability Swift クラスを Objective-C から使用 Cocoa API を Swift コードから利用 2. Mix and Match Objective-C ファイルと Swift ファイルを ひとつのプロジェクトに混在して併用 3. Migration 既存の Objective-C コードを Swift から Swift らしい構文で利用
Swift の特徴
1. Fast ⚫ Objective-C より速いらしい ⚫ 静的解決が主体 ⚫ 最適化しやすい言語設計
2. Modern Objective-C NSArray *array = @[ @"A", @"B", @"C" ]; NSString *string = [array componentsJoinedByString:@", "]; NSLog(@"Value: %@", string); Swift let array = [ "A", "B", "C" ] let string = join(", ", array) println("Value: \(string)")
3. Safe 不測を生まないコードが書ける ▶ 不測を含まないコードを強要される ⚫ nil を意識したコーディング ⚫ 型は揃えて計算する ⚫ switch で全ケースの網羅が必要 ⚫ 例外の廃止
4. Interactive ビルド操作不要でコードを実行可能 ⚫ Xcode からの逐次実行 Playground ⚫ ターミナルからの逐次実行 #!/usr/bin/swift
Objective-C without the C
行末文字からの訣別 行末のセミコロンを省略可能に Objective-C i += 10; Swift i += 10
条件文の括弧からの訣別 評価式の外側括弧を省略可能に Objective-C if (i == 10) { } Swift if i == 10 { }
プリミティブからの脱却 すべての型の対等な扱いが可能に ⚫ Int や enum も機能を持てる ⚫ 関数も変数で普通に扱える
C リテラルからの訣別 C リテラルの考慮が不要に Objective-C NSString *str = @"OBJC STRING"; NSNumber *num = @10; char* str = "C STRING"; int num = 10; Swift let str:String = "SWIFT STRING" let num:Int = 10
リテラル表現の簡素化
オブジェクトを意味する "@" が不要に
Objective-C
NSArray *arr = @[ @5, @10 ];
NSDictionary *dic = @{ @"K1":@1, @"K2":@2 };
Swift
let arr:[Int] = [ 5, 10 ]
let dic:[String:Int] = [ "K1": 1, "K2": 2 ]
変数の刷新 二種類の変数を利用可能に Objective-C NSInteger i = 10; const NSInteger i = 10; NSString* s = @"TEXT"; NSMutableString* s = [@"TEXT" mutableCopy]; Swift var i = 10 let i = 10 let s = "TEXT" var s = "TEXT"
文字列リテラルの拡張(展開) リテラル内で変数を展開可能に Objective-C NSString *str = [NSString stringWithFormat:@"Name=%@, Value=%d", name, value]; Swift let str:String = "Name=\(name), Value=\(value)"
文字列リテラルの拡張(連結) 演算子で文字列を連結可能に Objective-C NSString *str = [@"MSM" stringByAppendingString:@"2014"]; Swift let str:String = "MSM" + "2014"
文字列リテラルの拡張(比較) 演算子による文字列比較が可能に Objective-C if ([string1 isEqualToString:string2]) { } Swift if string1 == string2 { }
名前付き引数 引数にラベル名を付与可能に Objective-C [MyClass methodWithValue:10.0 ofType:@"$"] Swift MyClass.method(value:10.0, ofType:"$")
新しいデータ型 しがらみのないスマートな書式に Swift // タプル…複数の型を自由に組み合わせられる let value:(Int,String) = (200, "SWIFT") // nil 許容型…値の他に「ない」状態を扱える let value:Int? = nil // 値つき列挙型…自由な値を持てる列挙子 enum Enumerate { case Name(String) case NoName }
switch 構文の大幅な拡張 整数値リテラル以外でも分岐が可能に ⚫ 変数に格納した値を使った分岐 ⚫ 範囲による分岐 ⚫ 文字列による分岐 ⚫ タプルの値に応じた分岐 ⚫ 値つき列挙型の値に応じた分岐
数値リテラル さりげなく嬉しい機能 let dec = 200 // 10 進数 let hex = 0xc8 // 16 進数 let oct = 0o310 // 8 進数 let bin = 0b11001000 // 2 進数 let d = 2.10 let d = 1.25e-4 let d = 0x15p3 // 1.25 ×10-4 // 0x15×23
Objective-C without the C ほかにもいろいろ ⚫ ヘッダーファイル不要 ⚫ 同じ名前で異なる引数の関数 ⚫ 引数の既定値
Objective-C without the C C 言語のしがらみを捨てることで 言語機能を大幅に向上
Swift 不不変値 可変値 構造体 プロトコル ジェネリック Objective-C C
Swift の新しい概念
Closure
即席関数をシンプルに作って使える
Swift
// クロージャの定義
let isOK:(Int)->Bool = {(code:Int)->Bool in
return contains(200..<300, code)
}
// 関数のように実行
let result = isOK(200)
// 別の関数の引数に渡して実行
let result = contains(statuses, isOK)
Type inference 型が明らかなら記述不要 ⚫ 初期値を伴う変数や定数の宣言 ⚫ コレクションから要素を順次取得 ⚫ 列挙型を扱うことが明確な場合 ⚫ 制御構文で let で値の対応を取る ⚫ クロージャの戻り値や引数
Multiple return types
戻り値で複数の値を返せる
Swift
func getStatus()->(code:Int, status:String) {
return (200, "OK")
}
Swift
enum Status {
case OK
case Failed(String)
}
func getStatus()->Status {
return Status.OK
}
Generics
型に縛られない実装
⚫
任意の型を扱える
⚫
コードの共通化・実装の効率化
⚫
プロトコル主体のコーディング
Swift
func add<T:IntegerArithmeticType>(v1:T, v2:T)->T {
return value1 + value2
}
Swift の新しい概念 Namespaces モジュール単位での名前空間 ⚫ モジュール単位で空間を分離 ⚫ 同じ名前の異なる型を識別可能 Swift import MyModule1 import MyModule2 let obj1 = MyModule1.MyClass() let obj2 = MyModule2.MyClass()
Objective-C との互換性
Interoperability Objective-C と Swift の相互運用
Swift と Objective-C の互換性 Interoperability Swift クラスを Objective-C で使用可能 ⚫ NSObject の継承または @objc 属性が必須 ⚫ メソッド名が Objective-C 的に自動調整 ⚫ ⚫ @objc クラスではインスタンスを返すための クラスメソッドの実装が必要 Objective-C にない機能を使ったものは不可 オーバーロード, Generics, …
Swift と Objective-C の互換性
Interoperability
Swift クラスを Objective-C で使用可能
Swift
class MyClass : NSObject {
var value:Int
init(value:Int)
}
Objective-C
MyClass* obj
= [[MyClass alloc] initWithValue:10];
obj.value;
― #import "PROJNAME-Swift.h" で利用可能に ―
Swift と Objective-C の互換性 Interoperability Cocoa API を Swift から利用可能 ⚫ ほぼ全てを Swift らしいコードで利用可能 ⚫ 利用できないものもある Swift let value:NSString = "TEST STRING" value.stringByReplacingOccurrencesOfString("TEST", withString: "SWIFT", options: NSStringCompareOptions.LiteralSearch, range: NSMakeRange(0, value.length)) ― import Foundation 等で利用可能に ―
Swift と Objective-C の互換性 Mix and Match Objective-C と Swift との混在
Swift と Objective-C の互換性 Mix and Match Objective-C ファイルと Swift ファイルを混在
Swift と Objective-C の互換性 Migration 既存の Objective-C を Swift で活用
Swift と Objective-C の互換性 Migration 自作 Objective-C クラスを Swift で使用 ⚫ ⚫ ⚫ プロジェクトの Build Settings で Objective-C Bridging Header を登録 そこへ Swift で使いたいヘッダーファイルを #import すると Swift で利用可能になる C++ / Objective-C++ コードは利用不可 ヘッダーに C++ 固有の機能さえなければ OK ― Swift 側で import する必要なく利用可能 ―
Swift と Objective-C の互換性 Migration 自作 Objective-C クラスを Swift で使用 Objective-C @interface MyClass : NSObject @property (readwrite) NSInteger value; - (instancetype)initWithValue:(NSInteger)value; @end Swift let obj = MyClass(value:10) obj.value
Objective-C と Swift の 相互乗り入れが非常にしやすい ― 小さい単位での Swift への移行が可能 ―
Swift 現代らしさを積極的に取り入れながら 既存の環境でもすぐに使える言語
鍵を握るところ
2種類の変数 変数が意味を持つ時代へ • 不変値変数 let 値 を表現する • 可変値変数 var 状態 を表現する
2種類の変数 変数が意味を持つ時代へ // 平面を動く物体の座標 var location:(x,y) // 平面座標の値 let location:(x,y)
オプショナル 存在しないを扱える型 ⚫ 値がある場合とない場合をとる ⚫ 存在しないことを意識でき ⚫ Optional<T> と ImplicitlyUnwrappedOptional<T>
生まれ変わった構造体 変数に特化した型の誕生 ⚫ 値や状態を表現する ⚫ 内容を自由に設計できる ⚫ 格納先に応じて振る舞いが変化
列挙型と switch 安全性に着目した網羅性のコンセプト ⚫ 選択肢を有限に絞れる ⚫ 取り得る範囲が明確になる ⚫ 想定外を検出できる
Swift を楽しみましょう!