Swiftおさらい
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

Swiftおさらい

  • 8,752 views
Uploaded on

この資料は発表当時(2014/6/24)のものです。既に仕様が変わっている部分もありますので、ご注意ください。

この資料は発表当時(2014/6/24)のものです。既に仕様が変わっている部分もありますので、ご注意ください。

More in: Travel , Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
8,752
On Slideshare
7,138
From Embeds
1,614
Number of Embeds
9

Actions

Shares
Downloads
22
Comments
0
Likes
33

Embeds 1,614

http://ngw.jp 1,387
https://swot.jp 100
https://twitter.com 83
http://b.hatena.ne.jp 31
http://s.deeeki.com 8
http://slideshare-download.seesaa.net 2
http://webcache.googleusercontent.com 1
https://tweetdeck.twitter.com 1
http://cache.yahoofs.jp 1

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Swift おさらい LINE Developer Meetup in Fukuoka #5 @taketin 2014/06/24
  • 2. 自己紹介 @taketin LINE Fukuoka iOS developer PHP, Ruby, Objective-C (だいたい)毎週木曜19:30 〜 Fukuoka.swift よろしくお願いします 初めて買ったマック Macintosh Performa LC630
  • 3. Swift とは?
  • 4. https://developer.apple.com/swift/ http://swift-lang.org/main/
  • 5. https://developer.apple.com/swift/ http://swift-lang.org/main/ ◯
  • 6. Swift is “Objective-C without the C” • Swift言語の開発は2010年7月にAppleエンジニアの 個人プロジェクトから始まった • 設計するにあたって影響を受けた言語は Objective-C、 Rust、Haskell、Ruby、Python、C#、 CLU等 via: http://jp.techcrunch.com/2014/06/05/20140604apples-new-programming-language-has-been-in-development-for-nearly-four-years/#Swift
  • 7. 特徴 • モダン クロージャやタプル、ジェネリックプログラミング、 Optional型の採用。 via: http://ja.wikipedia.org/wiki/Swift_(プログラミング言語)
  • 8. 特徴 • モダン クロージャやタプル、ジェネリックプログラミング、 Optional型の採用。 • 安全 静的な型チェック、変数の初期化の強制、数値型のオーバーフローの検査、 自動参照カウント (ARC) によるメモリ管理など。 via: http://ja.wikipedia.org/wiki/Swift_(プログラミング言語)
  • 9. 特徴 • モダン クロージャやタプル、ジェネリックプログラミング、 Optional型の採用。 • 安全 静的な型チェック、変数の初期化の強制、数値型のオーバーフローの検査、 自動参照カウント (ARC) によるメモリ管理など。 • 高速 Objective-C より速い via: http://ja.wikipedia.org/wiki/Swift_(プログラミング言語)
  • 10. 特徴 • モダン クロージャやタプル、ジェネリックプログラミング、 Optional型の採用。 • 安全 静的な型チェック、変数の初期化の強制、数値型のオーバーフローの検査、 自動参照カウント (ARC) によるメモリ管理など。 • 高速 Objective-C より速い • インタラクティブ コンパイラ言語だが、インタプリタとしてスクリプトを実行することも可能。対話実行環境 (REPL) 付属。 コードの実行結果をグラフィカルに確認しながら開発できる “Playgrounds” を実装。 via: http://ja.wikipedia.org/wiki/Swift_(プログラミング言語)
  • 11. では仕様を見ていきましょう
  • 12. 変数 (var) var city: String = “Hakata” 変数、定数
  • 13. 変数 (var) var city: String = “Hakata” 定数 (let) let city: String = “Hakata” city = “Tenjin” // error 変数、定数
  • 14. 変数 (var) var city: String = “Hakata” 定数 (let) let city: String = “Hakata” city = “Tenjin” // error 型推論 var city = “Tenjin” // String 型と推論 変数、定数
  • 15. 変数名は日本語、ユニコード絵文字も 一部使用可。 var 街 = “博多” 変数、定数
  • 16. 暗黙の型変換はしない。 let label = "old" let age = 36 String(age) + label 型変換
  • 17. () で展開 var city = “Hakata” “welcome to (city).” 変数展開
  • 18. () で展開 var city = “Hakata” “welcome to (city).” 式の評価もできる var section = “Ekimae” “welcome to (city + section).” ※ シングルクォートは使えない。 変数展開
  • 19. nil 許容 (型の後ろに ? を付ける) var optional: String = nil // error Optional Value
  • 20. nil 許容 (型の後ろに ? を付ける) var optional: String = nil // error var optional: String? = nil 通常、変数に nil を入れる事はできない。 Optional Value
  • 21. var foo: String? = “bar” // {Some “bar”} “指定された型の値”、もしくは “nil” の2つの要素を持てるように曖昧な形に 「wrap」されている という表現を使う。 Optional Value
  • 22. 「unwrap」する var optional :String? = “foo” // {Some “foo”} var notOptional = optional! // “foo” ImplicitlyUnwrappedOptional
  • 23. 「unwrap」する var optional :String? = “foo” // {Some “foo”} var notOptional = optional! // “foo” 確実に nil では無いと判断できる場合のみ使用する。 値が nil の場合はランタイムエラーが発生する。 (fatal error: Can't unwrap Optional.None) ImplicitlyUnwrappedOptional
  • 24. 特別な評価式 var optional :String? = “foo” if let notOptional = optional { println(“(notOptional) is not nil”) } else { println(“nil”) } optionalのnil判定を行い、代入しつつbool値を返す ImplicitlyUnwrappedOptional
  • 25. ? は enum Optional<T> ! は struct ImplicitlyUnwrappedOptional<T> のシンタックスシュガー ImplicitlyUnwrappedOptional
  • 26. ? は enum Optional<T> ! は struct ImplicitlyUnwrappedOptional<T> のシンタックスシュガー ⌘ + Click で定義を見れるので、中身を 色々見て理解を深めましょう ImplicitlyUnwrappedOptional
  • 27. class Users { class User { var name: String = "taketin" } var user: User? = User() } OptionalChaining
  • 28. class Users { class User { var name: String = "taketin" } var user: User? = User() } OptionalChaining var users: Users? = Users() if let name = users?.user?.name { println(name) // “taketin” } else { println("error!") }
  • 29. class Users { class User { var name: String = "taketin" } var user: User? = nil } OptionalChaining var users: Users? = Users() if let name = users?.user?.name { println(name) } else { println("error!") // error! }
  • 30. var response = (404, "NotFound") Tuple
  • 31. var response = (404, "NotFound") response.0 // 404 response.1 // “NotFound” Tuple
  • 32. var response = (404, "NotFound") response.0 // 404 response.1 // “NotFound” // ラベル response = (status:404, description:”NotFound”) Tuple
  • 33. var response = (404, "NotFound") response.0 // 404 response.1 // “NotFound” // ラベル response = (status:404, description:”NotFound”) response.status // 404 response.description // “NotFound” Tuple
  • 34. true or false Bool値
  • 35. true or false YES or NO は無くなりました Bool値
  • 36. 配列 var a = [1, 2, 3] var b = String[]() var c = Array<String>() var d = Double[](count: 3, repeatedValue: 0.0) // [0.0, 0.0, 0.0] コレクション
  • 37. 配列イテレーション var array = [1, 2, 3] for value in array { println(value) } コレクション
  • 38. 配列のコピー var a = [1, 2, 3] var b = a // [1, 2, 3] (参照渡し) var a[0] = 9 // [9, 2, 3] b // [9, 2, 3] コレクション
  • 39. 配列のコピー var a = [1, 2, 3] var b = a // [1, 2, 3] (参照渡し) a.append(4) // [1, 2, 3, 4] b // [1, 2, 3] コレクション
  • 40. 配列のコピー var a = [1, 2, 3] var b = a // [1, 2, 3] (参照渡し) a.append(4) // [1, 2, 3, 4] (コピー作成) b // [1, 2, 3] 配列長が変わると新しい配列を作る コレクション
  • 41. 配列のコピー var a = [1, 2, 3] var b = a.copy() // 値渡し コレクション
  • 42. 配列のコピー var a = [1, 2, 3] var b = a.copy() // 値渡し または var b = a b.unshare() // 参照を切る コレクション
  • 43. 配列範囲指定 var array = [1, 2, 3] array[0..2] = [1] // [1, 3] array[0...2] = [1] // [1] コレクション
  • 44. 配列範囲指定 var array = [1, 2, 3] array[0..2] = [1] // [1, 3] array[0...2] = [1] // [1] .. は未満 ... は以下(Rubyと逆なので注意) コレクション
  • 45. ディクショナリ var a = Dictionary<Int, String>() var b = [1:”foo”, 2:”bar”] b[1] = nil // [2:”bar”] コレクション
  • 46. ディクショナリ キーの型は hashable で無くてはならない。 String, Int, Double, Bool はデフォルトで hashable (Hashable プロトコル継承) コレクション
  • 47. ディクショナリイテレーション for (key, value) in dictionary {} // キーのみ、値のみ for key in dictionary.keys {} for values in dictionary.values {} コレクション
  • 48. ディクショナリのコピー var a = [1:”a”, 2:”b”] var b = a // 値渡し a[1] = “z” // [1:”z”, 2:”b”] b // [1:”a”, 2:”b”] コレクション
  • 49. if文 if 条件式 { /* Snip */ } else if 条件式 { /* Snip */ } コントロール
  • 50. while文 while 条件式 { /* Snip */ } do { /* Snip */ } while 条件式 コントロール
  • 51. for文 for var index = 0; index < 5; index++ { /* Snip */ } for index in 0..5 { /* Snip */ } コントロール
  • 52. switch文 let foo = "hoge" switch foo { case "bar": println("bar") case "baz", "hoge": println("baz or hoge") default: println("other") } コントロール
  • 53. switch文 基本 break 動作。 fallthrough を指定すると次の case も処理。 コントロール
  • 54. switch文 いろいろなマッチング case 1...3: // Range case (_, 0): // tuple case (let x, 0): // value bindings case let (x, y) where x == y: // where コントロール
  • 55. enum Fukuoka { case Tenjin case Daimyo case Hakata case Nakasu } 列挙型 (Enum)
  • 56. enum Fukuoka { case Tenjin case Daimyo case Hakata case Nakasu } 列挙型 (Enum) var foo = Fukuoka.Tenjin switch foo { case .Tenjin case .Daimyo case .Hakata case .Nakasu }
  • 57. enum Fukuoka { case Tenjin case Daimyo case Hakata case Nakasu } 列挙型 (Enum) var foo = Fukuoka.Tenjin switch foo { case .Tenjin case .Daimyo case .Hakata } switch must be exhaustive, consider adding a default clause
  • 58. enum Rank: Int { case One = 1 case Two, Three, Four } 列挙型 (Enum)
  • 59. enum Rank: Int { case One = 1 case Two, Three, Four } var rank = Rank.Two // (Enum Value) 列挙型 (Enum)
  • 60. enum Rank: Int { case One = 1 case Two, Three, Four } var rank = Rank.Two // (Enum Value) rank.toRaw() // 2 列挙型 (Enum)
  • 61. enum Rank: Int { case One = 1 case Two, Three, Four } var rank = Rank.Two // (Enum Value) rank.toRaw() // 2 Rank.fromRaw(3) // (Enum Value) 列挙型 (Enum)
  • 62. enum Fukuoka: String { case Tenjin = "天神" case Hakata = "博多" } var city = Fukuoka.Hakata 列挙型 (Enum)
  • 63. enum Fukuoka: String { case Tenjin = "天神" case Hakata = "博多" } var city = Fukuoka.Hakata city = .Tenjin // 型が分かっているので省略可能 列挙型 (Enum)
  • 64. enum Fukuoka: String { case Tenjin = "天神" case Hakata = "博多" func toKana() -> String { switch self { case .Tenjin: return "てんじん" case .Hakata: return "はかた" } } } 列挙型 (Enum)
  • 65. enum Fukuoka: String { case Tenjin = "天神" case Hakata = "博多" func toKana() -> String { switch self { case .Tenjin: return "てんじん" case .Hakata: return "はかた" } } } 列挙型 (Enum) var city = Fukuoka.Tenjin // 天神
  • 66. enum Fukuoka: String { case Tenjin = "天神" case Hakata = "博多" func toKana() -> String { switch self { case .Tenjin: return "てんじん" case .Hakata: return "はかた" } } } 列挙型 (Enum) var city = Fukuoka.Tenjin // 天神 city.toKana() // てんじん
  • 67. Associated Values enum APIResponse { case Success(Int, String) case Error(Int, String, NSError) } 列挙型 (Enum)
  • 68. Associated Values enum APIResponse { case Success(Int, String) case Error(Int, String, NSError) } // if success var res = APIResponse.Success(200, “OK”) 列挙型 (Enum)
  • 69. Associated Values enum APIResponse { case Success(Int, String) case Error(Int, String, NSError) } // if success var res = APIResponse.Success(200, “OK”) // if error var res = APIResponse.Error(403, “Access denied”, error) 列挙型 (Enum)
  • 70. Associated Values switch res { case let .Success(httpStatus, message): … // 成功時処理 case let .Error(httpStatus, message, error): … // エラー処理 } 列挙型 (Enum)
  • 71. Associated Values switch res { case let .Success(httpStatus, message): … // 成功時処理 case let .Error(httpStatus, message, error): … // エラー処理 } a.k.a discriminated unions, tagged unions, or variants. 列挙型 (Enum)
  • 72. func foo(bar: String, baz: Int) -> String {} 関数
  • 73. func foo(bar: String, baz: Int) -> String {} // キーワード指定可 func foo(aaa bar: String, bbb baz: Int) -> String {} 関数
  • 74. func foo(bar: String, baz: Int) -> String {} // キーワード指定可 func foo(aaa bar: String, bbb baz: Int) -> String {} // 引数のデフォルト値指定可 func foo(bar: String, baz: Int = 1) -> String {} 関数
  • 75. // 引数の可変長指定可 (Variadic Parameter) func foo(bar: String, baz: Int...) -> String {} 関数
  • 76. // 引数の可変長指定可 (Variadic Parameter) func foo(bar: String, baz: Int...) -> String {} // 引数の参照渡し (inoutラベル) func swapValue(inout a: Int, inout b: Int) {} swapValue(&a, &b) 関数
  • 77. ネスト func foo() -> Int { func bar() { func baz() { } baz() } bar() } foo() 関数
  • 78. 返り値が関数 func foo() -> ((Int, Int) -> String) { func bar(number: Int, number2: Int) -> String { return String(number + number2) } return bar } var bar = foo() bar(1,2) 関数
  • 79. 返り値がタプル func getTuple() -> (Double, Int, String) { return (1.0, 2, "3") } var result = getTuple() result.0 // 1.0 result.1 // 2 result.2 // "3" 関数
  • 80. 基本形 sort([“A”, “C”, “B”], { (s1: String, s2: String) -> Bool in return s1 < s2 }) // [“A”, “B”, “C”] クロージャ
  • 81. 型推論が効く sort([“A”, “C”, “B”], { (s1: String, s2: String) -> Bool in return s1 < s2 }) ▼ sort([“A”, “C”, “B”], { s1, s2 in return s1 < s2 }) クロージャ
  • 82. 式が1つだけの場合 return が省略できる sort([“A”, “C”, “B”], { s1, s2 in return s1 < s2 }) ▼ sort([“A”, “C”, “B”], { s1, s2 in s1 < s2 }) クロージャ
  • 83. 引数をプレースホルダで置換できる sort([“A”, “C”, “B”], { s1, s2 in s1 < s2 }) ▼ sort([“A”, “C”, “B”], { $0 < $1 }) クロージャ
  • 84. Operator Functions を使用する sort([“A”, “C”, “B”], { $0 < $1 }) ▼ sort([“A”, “C”, “B”], < ) クロージャ
  • 85. Operator Functions を使用する sort([“A”, “C”, “B”], { $0 < $1 }) ▼ sort([“A”, “C”, “B”], < ) 式によってはここまで簡略化できる クロージャ
  • 86. Trailing Closures sort([“A”, “C”, “B”], { $0 < $1 }) ▼ sort([“A”, “C”, “B”]) { $0 < $1 } クロージャ
  • 87. Trailing Closures sort([“A”, “C”, “B”], { $0 < $1 }) ▼ sort([“A”, “C”, “B”]) { $0 < $1 } 引数の最後がクロージャの場合、外出し記述可 クロージャ
  • 88. Trailing Closures sort([“A”, “C”, “B”], { $0 < $1 }) ▼ sort([“A”, “C”, “B”]) { $0 < $1 } 引数の最後がクロージャの場合、外出し記述可 sort([“A”, “C”, “B”]) { < } ※これはエラーになった クロージャ
  • 89. blocks 内で self を使った場合の循環参照回避 // lang: Objective-C __weak BlockOwner *weakSelf = self; _block = ^() { NSLog(@"name: %@", weakSelf.name); }; クロージャ
  • 90. blocks 内で self を使った場合の循環参照回避 // lang: Swift self.aProperty = { [unowned self] in // closure capture list self.doSomething() } クロージャ
  • 91. blocks 内で self を使った場合の循環参照回避 // lang: Swift self.aProperty = { [unowned self] in // closure capture list self.doSomething() } 引き続き注意が必要 >< クロージャ
  • 92. class Foo { var bar: String init(baz: Int) { // コンストラクタ self.bar = baz // propertyイニシャライズ必須 } func hoge(fuga: Int, piyo: Int) {} deinit {} // デストラクタ } クラス
  • 93. コンストラクタ init() がコンストラクタ 引数がある場合 init(baz: Int) はインスタンス生成時に引数ラ ベルを指定する必要あり var foo = Foo(baz: 1) クラス
  • 94. コンストラクタ init() がコンストラクタ 引数がある場合 init(baz: Int) はインスタンス生成時に引数ラ ベルを指定する必要あり var foo = Foo(baz: 1) ただし、_ をラベルにする事で回避できる init(_ bar:Int) // var foo = Foo(1) クラス
  • 95. コンビニエンスコンストラクタ class Foo { var bar:Int init(baz: Int) { self.bar = baz } func hoge(fuga:Int, piyo:Int) {} convenience init() { self.init(baz:0) } } クラス
  • 96. コンビニエンスコンストラクタ var foo = Foo() foo.bar // 0 コンストラクタ引数を省略する事ができる。その場合 convenience init 内に書かれた値で初期化される。 クラス
  • 97. 継承 class Foo : Bar { } クラス
  • 98. 継承 class Foo { } Objective-C と違い、基底クラスが無い場合は 継承を省略できる クラス
  • 99. メソッドオーバーライド class Foo : Bar { override func baz() { } } クラス
  • 100. メソッドオーバーライド class Foo : Bar { override func baz() { } } スーパークラスと同名のメソッドを定義していても、 override が無ければ別メソッドとして認識される クラス
  • 101. コピー var foo1 = FooClass() foo1.bar // 10 var foo2 = foo1 foo2.bar // 10 クラス
  • 102. コピー var foo1 = FooClass() foo1.bar // 10 var foo2 = foo1 foo2.bar // 10 foo1.bar = 50 foo2.bar // 50 クラス
  • 103. コピー var foo1 = FooClass() foo1.bar // 10 var foo2 = foo1 // クラスは参照渡し foo2.bar // 10 foo1.bar = 50 foo2.bar // 50 クラス
  • 104. コピー 値渡しでコピーしたい場合は、 import Foundation して NSCopying を継承。 copyWithZone() メソッドを自前で実装する。 (Objective-C と同じイメージ) via: http://qiita.com/taketin@github/items/abcd2bea9e5888afa141 クラス
  • 105. 比較 (===) var foo1 = FooClass() var foo2 = FooClass() foo1 === foo2 // false クラス
  • 106. 比較 (===) var foo1 = FooClass() var foo2 = FooClass() foo1 === foo2 // false var foo3 = foo1 foo3 === foo1 // true クラス
  • 107. 比較 (===) var foo1 = FooClass() var foo2 = FooClass() foo1 === foo2 // false var foo3 = foo1 foo3 === foo1 // true インスタンスのアドレス比較を行う クラス
  • 108. Getter, Setter class Foo { var bar: Int { get { return 10 } set { self.baz = newValue } } var baz: Int = 0 } クラス - プロパティ
  • 109. Getter, Setter class Foo { var bar: Int { get { return 10 } set { self.baz = newValue } } var baz: Int = 0 } setter は “newValue” で新しい値を参照できる クラス - プロパティ
  • 110. Getter, Setter class Foo { var bar: Int { get { return 10 } } var baz: Int = 0 } get のみ書く事で ReadOnly として定義できる クラス - プロパティ
  • 111. willSet, didSet class Foo { var bar:Int { willSet {} didSet {} } } Objective-C の KVO のような動きができる クラス - プロパティ
  • 112. 遅延ロード class Foo { @lazy var bar = SomeClass() } var foo = Foo() // ここでは bar 未初期化 foo.bar // ここで bar 初期化 クラス - プロパティ
  • 113. Type Property Syntax class Foo { class var bar:Int { return 1 } } Foo.bar // 1 クラス - プロパティ
  • 114. class Foo { var bar:Int = 5 init() {} subscript(index: Int) -> Int { return self.bar * index } } Subscript
  • 115. class Foo { var bar:Int = 5 init() {} subscript(index: Int) -> Int { return self.bar * index } } var foo = Foo(); foo[10] // 50 オブジェクトへの添字アクセスができる Subscript
  • 116. class Foo { var bar:Int = 5 init() {} subscript(index: Int) -> Int { get { /* Snip */ } set { /* Snip */ } } } アクセスコントロールも可能 Subscript
  • 117. イニシャライズ struct Foo { var bar: Int = 1 func baz() -> String { return "test" } } var foo = Foo() 構造体 (Structure)
  • 118. イニシャライズ struct Foo { var bar: Int func baz() -> String { return "test" } } var foo = Foo(bar: 1) 構造体 (Structure)
  • 119. mutating struct Foo { var bar: Int = 1 func baz() { bar = 10 // コンパイルエラー } } 構造体 (Structure)
  • 120. mutating struct Foo { var bar: Int = 1 mutating func baz() { bar = 10 } } 構造体 (Structure)
  • 121. static variable struct Foo { static var bar: Int = 1 } Foo.bar // 1 構造体 (Structure)
  • 122. コピー var foo1 = Foo() foo1.bar // 1 var foo2 = foo1 foo1.bar = 10 構造体 (Structure)
  • 123. コピー var foo1 = Foo() foo1.bar // 1 var foo2 = foo1 foo1.bar = 10 foo2.bar // 1 構造体は値渡し(クラスは参照) 構造体 (Structure)
  • 124. protocol FooProtocol { var bar: String { get } func baz() -> String } Protocol
  • 125. protocol FooProtocol { var bar: String { get } func baz() -> String } class FooClass : FooProtocol { var bar: String = “hoge” func baz() -> String { /* Snip */ } } Protocol
  • 126. protocol FooProtocol { var bar: String { get set } // getter, setter 必須 func baz() -> String } class FooClass : FooProtocol { var bar: String { get { /* Snip */ } // set が無いのでコンパイルエラー } Protocol
  • 127. protocol FooProtocol { var bar: String mutating func baz() -> String } struct FooStruct : FooProtocol { var bar: String = “hoge” mutating func baz() -> String { /* Snip */ } } Protocol
  • 128. protocol FooProtocol { } protocol BarProtocol { } class FooClass : FooProtocol, BarProtocol { /* Snip */ } 複数継承も可能 Protocol
  • 129. extension String { func twice() -> String { return "(self) (self)" } } Extention
  • 130. extension String { func twice() -> String { return "(self) (self)" } } var str = “hello” str.twice() // “hello hello” クラスだけでなく型などにも適用できる Extention
  • 131. extension String : FooProtocol { func twice() -> String { return "(self) (self)" } } プロトコルの継承もできる Extention
  • 132. func Foo <任意の型> () {} 型の形式は UpperCamelCase。<HogeType> など。 短く <T> 等が慣習的に使われている。 Generics
  • 133. 型制約無し func repeat<T>(item: T, times: Int) -> T[] { var result = T[]() for i in 0..times { result += item } return result } Generics
  • 134. 型制約無し func repeat<T>(item: T, times: Int) -> T[] { var result = T[]() for i in 0..times { result += item } return result } repeat(“knock”, 4) // [“knock”, “knock”, “knock”, “knock”] Generics
  • 135. 型制約無し func repeat<T>(item: T, times: Int) -> T[] { var result = T[]() for i in 0..times { result += item } return result } repeat(“knock”, 4) // [“knock”, “knock”, “knock”, “knock”] repeat(10, 4) // [10, 10, 10, 10] Generics
  • 136. 型制約有り func findIndex<T: Equatable>(array: T[], valueToFind: T) -> Int? { for (index, value) in enumerate(array) { if value == valueToFind { return index } } return nil } Generics
  • 137. 型制約有り func findIndex<T: Equatable>(array: T[], valueToFind: T) -> Int? { for (index, value) in enumerate(array) { if value == valueToFind { return index } } return nil } プロトコル継承の制約を定義できる Generics
  • 138. Any & AnyObject var array : Any[] = ["1", 2, Foo()] TypeCasting
  • 139. Any & AnyObject // 関数型以外なんでも入れる事ができる var array : Any[] = ["1", 2, Foo()] TypeCasting
  • 140. Any & AnyObject // 関数型以外なんでも入れる事ができる var array : Any[] = ["1", 2, Foo()] var array2 : AnyObject[] = [Foo(), Bar(), Baz()] TypeCasting
  • 141. Any & AnyObject // 関数型以外なんでも入れる事ができる var array : Any[] = ["1", 2, Foo()] // クラスのインスタンスのみ入れる事ができる var array2 : AnyObject[] = [Foo(), Bar(), Baz()] TypeCasting
  • 142. 型チェック var array : Any[] = ["1", 2, 3] for obj in array { if obj is Int { println("(obj) is Int") // 2 is Int & 3 is Int } } TypeCasting
  • 143. ダウンキャスト // obj には Base クラスのインスタンスが入っている // Base を継承した Bar クラスが定義されている let bar = obj as Bar // Bar クラス TypeCasting
  • 144. ダウンキャスト // obj には Base クラスのインスタンスが入っている // Base を継承した Bar クラスが定義されている let bar = obj as Bar もし obj に Bar へダウンキャストできないオブジェクトが入って いたらランタイムエラー TypeCasting
  • 145. ダウンキャスト // obj には Base クラスのインスタンスが入っている // Base を継承した Bar クラスが定義されている let bar = obj as? Bar オプショナルで安全 TypeCasting
  • 146. ダウンキャスト for obj in array { if obj is Bar { let bar = obj as Bar /* Snip */ } } TypeCasting for obj in array { if let bar = obj as? Bar { /* Snip */ } }
  • 147. ダウンキャスト for obj in array { if obj is Bar { let bar = obj as Bar /* Snip */ } } TypeCasting for obj in array { if let bar = obj as? Bar { /* Snip */ } } OptionalValue の評価式を使って、評価 > 代入が簡単に書ける
  • 148. 存在する演算子を拡張 @infix func + (left: String, right: Int) -> String { return "(left) (right)" } Operator Functions
  • 149. 存在する演算子を拡張 @infix func + (left: String, right: Int) -> String { return "(left) (right)" } “number” + 1 // “number 1” Operator Functions
  • 150. 存在しない演算子を定義 @infix func +++ (left: String, right: Int) -> String { return "(left) (right)" } “number” +++ 1 Operator Functions
  • 151. 存在しない演算子を定義 @infix func +++ (left: String, right: Int) -> String { return "(left) (right)" } “number” +++ 1 // コンパイルエラー Operator Functions
  • 152. 存在しない演算子を定義 operator infix +++ {} @infix func +++ (left: String, right: Int) -> String { return "(left) (right)" } “number” +++ 1 // “number 1” Operator Functions
  • 153. その他詳細は公式ドキュメントをご覧くだ さい。 https://developer.apple. com/library/prerelease/ios/documentation/swift/conceptual/swift_prog ramming_language/
  • 154. ドキュメントに見当たりません おまけ:正規表現
  • 155. えっ、、、 おまけ:正規表現
  • 156. NSRegularExpression を利用して Perl ライクな =~ 演算子を使えるようにするライブラリがあるの でとりあえず利用すると良さそう。 https://github.com/kasei/SwiftRegex おまけ:正規表現
  • 157. “Namespacing is implicit in swift, all classes (etc) are implicitly scoped by the module (Xcode target) they are in. no class prefixes needed” 「Swiftにおいて名前空間は暗黙のうちに提供される。すべてのクラ スはそのモジュール (Xcode上のターゲット)によって暗黙のうちに スコープが制限される。クラスプレフィックスはもはや不要」 via: https://twitter.com/clattner_llvm/status/474730716941385729 おまけ:名前空間
  • 158. アクセス修飾子 (private, public) おまけ:今後の展望
  • 159. アクセス修飾子 (private, public) "We don't usually promise anything for the future, but in this case we are making an exception. Swift will have access control mechanisms." 「将来の約束は一般的にしてないんだけど、今回は例外。Swift にはアクセス制限のための仕組みを追加予定です」 via: http://stackoverflow.com/questions/24003918/does-swift-have-access-modifiers おまけ:今後の展望
  • 160. CocoaPods おまけ:今後の展望
  • 161. CocoaPods https://github.com/CocoaPods/CocoaPods/tree/swift https://github.com/CocoaPods/CocoaPods/pull/2222 着々と進行中の様です。待ちましょう。 おまけ:今後の展望
  • 162. 汎用言語として公開してくれないかなー おまけ:今後の希望
  • 163. LINE Fukuoka では Swift なら誰にも負けないと いうエンジニアさんを求めています! 更におまけ
  • 164. 福岡で一緒に LINE を育てていきましょう! https://linefukuoka.co.jp/career/developer 更におまけ
  • 165. ご清聴ありがとうございました。