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

Swiftおさらい

on

  • 6,658 views

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

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

Statistics

Views

Total Views
6,658
Views on SlideShare
5,686
Embed Views
972

Actions

Likes
28
Downloads
17
Comments
0

7 Embeds 972

http://ngw.jp 862
https://twitter.com 67
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
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Swiftおさらい Swiftおさらい Presentation Transcript

  • Swift おさらい LINE Developer Meetup in Fukuoka #5 @taketin 2014/06/24
  • 自己紹介 @taketin LINE Fukuoka iOS developer PHP, Ruby, Objective-C (だいたい)毎週木曜19:30 〜 Fukuoka.swift よろしくお願いします 初めて買ったマック Macintosh Performa LC630
  • Swift とは?
  • https://developer.apple.com/swift/ http://swift-lang.org/main/
  • https://developer.apple.com/swift/ http://swift-lang.org/main/ ◯
  • 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
  • 特徴 • モダン クロージャやタプル、ジェネリックプログラミング、 Optional型の採用。 via: http://ja.wikipedia.org/wiki/Swift_(プログラミング言語)
  • 特徴 • モダン クロージャやタプル、ジェネリックプログラミング、 Optional型の採用。 • 安全 静的な型チェック、変数の初期化の強制、数値型のオーバーフローの検査、 自動参照カウント (ARC) によるメモリ管理など。 via: http://ja.wikipedia.org/wiki/Swift_(プログラミング言語)
  • 特徴 • モダン クロージャやタプル、ジェネリックプログラミング、 Optional型の採用。 • 安全 静的な型チェック、変数の初期化の強制、数値型のオーバーフローの検査、 自動参照カウント (ARC) によるメモリ管理など。 • 高速 Objective-C より速い via: http://ja.wikipedia.org/wiki/Swift_(プログラミング言語)
  • 特徴 • モダン クロージャやタプル、ジェネリックプログラミング、 Optional型の採用。 • 安全 静的な型チェック、変数の初期化の強制、数値型のオーバーフローの検査、 自動参照カウント (ARC) によるメモリ管理など。 • 高速 Objective-C より速い • インタラクティブ コンパイラ言語だが、インタプリタとしてスクリプトを実行することも可能。対話実行環境 (REPL) 付属。 コードの実行結果をグラフィカルに確認しながら開発できる “Playgrounds” を実装。 via: http://ja.wikipedia.org/wiki/Swift_(プログラミング言語)
  • では仕様を見ていきましょう
  • 変数 (var) var city: String = “Hakata” 変数、定数
  • 変数 (var) var city: String = “Hakata” 定数 (let) let city: String = “Hakata” city = “Tenjin” // error 変数、定数
  • 変数 (var) var city: String = “Hakata” 定数 (let) let city: String = “Hakata” city = “Tenjin” // error 型推論 var city = “Tenjin” // String 型と推論 変数、定数
  • 変数名は日本語、ユニコード絵文字も 一部使用可。 var 街 = “博多” 変数、定数
  • 暗黙の型変換はしない。 let label = "old" let age = 36 String(age) + label 型変換
  • () で展開 var city = “Hakata” “welcome to (city).” 変数展開
  • () で展開 var city = “Hakata” “welcome to (city).” 式の評価もできる var section = “Ekimae” “welcome to (city + section).” ※ シングルクォートは使えない。 変数展開
  • nil 許容 (型の後ろに ? を付ける) var optional: String = nil // error Optional Value
  • nil 許容 (型の後ろに ? を付ける) var optional: String = nil // error var optional: String? = nil 通常、変数に nil を入れる事はできない。 Optional Value
  • var foo: String? = “bar” // {Some “bar”} “指定された型の値”、もしくは “nil” の2つの要素を持てるように曖昧な形に 「wrap」されている という表現を使う。 Optional Value
  • 「unwrap」する var optional :String? = “foo” // {Some “foo”} var notOptional = optional! // “foo” ImplicitlyUnwrappedOptional
  • 「unwrap」する var optional :String? = “foo” // {Some “foo”} var notOptional = optional! // “foo” 確実に nil では無いと判断できる場合のみ使用する。 値が nil の場合はランタイムエラーが発生する。 (fatal error: Can't unwrap Optional.None) ImplicitlyUnwrappedOptional
  • 特別な評価式 var optional :String? = “foo” if let notOptional = optional { println(“(notOptional) is not nil”) } else { println(“nil”) } optionalのnil判定を行い、代入しつつbool値を返す ImplicitlyUnwrappedOptional
  • ? は enum Optional<T> ! は struct ImplicitlyUnwrappedOptional<T> のシンタックスシュガー ImplicitlyUnwrappedOptional
  • ? は enum Optional<T> ! は struct ImplicitlyUnwrappedOptional<T> のシンタックスシュガー ⌘ + Click で定義を見れるので、中身を 色々見て理解を深めましょう ImplicitlyUnwrappedOptional
  • class Users { class User { var name: String = "taketin" } var user: User? = User() } OptionalChaining
  • 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!") }
  • 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! }
  • var response = (404, "NotFound") Tuple
  • var response = (404, "NotFound") response.0 // 404 response.1 // “NotFound” Tuple
  • var response = (404, "NotFound") response.0 // 404 response.1 // “NotFound” // ラベル response = (status:404, description:”NotFound”) Tuple
  • var response = (404, "NotFound") response.0 // 404 response.1 // “NotFound” // ラベル response = (status:404, description:”NotFound”) response.status // 404 response.description // “NotFound” Tuple
  • true or false Bool値
  • true or false YES or NO は無くなりました Bool値
  • 配列 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] コレクション
  • 配列イテレーション var array = [1, 2, 3] for value in array { println(value) } コレクション
  • 配列のコピー var a = [1, 2, 3] var b = a // [1, 2, 3] (参照渡し) var a[0] = 9 // [9, 2, 3] b // [9, 2, 3] コレクション
  • 配列のコピー var a = [1, 2, 3] var b = a // [1, 2, 3] (参照渡し) a.append(4) // [1, 2, 3, 4] b // [1, 2, 3] コレクション
  • 配列のコピー var a = [1, 2, 3] var b = a // [1, 2, 3] (参照渡し) a.append(4) // [1, 2, 3, 4] (コピー作成) b // [1, 2, 3] 配列長が変わると新しい配列を作る コレクション
  • 配列のコピー var a = [1, 2, 3] var b = a.copy() // 値渡し コレクション
  • 配列のコピー var a = [1, 2, 3] var b = a.copy() // 値渡し または var b = a b.unshare() // 参照を切る コレクション
  • 配列範囲指定 var array = [1, 2, 3] array[0..2] = [1] // [1, 3] array[0...2] = [1] // [1] コレクション
  • 配列範囲指定 var array = [1, 2, 3] array[0..2] = [1] // [1, 3] array[0...2] = [1] // [1] .. は未満 ... は以下(Rubyと逆なので注意) コレクション
  • ディクショナリ var a = Dictionary<Int, String>() var b = [1:”foo”, 2:”bar”] b[1] = nil // [2:”bar”] コレクション
  • ディクショナリ キーの型は hashable で無くてはならない。 String, Int, Double, Bool はデフォルトで hashable (Hashable プロトコル継承) コレクション
  • ディクショナリイテレーション for (key, value) in dictionary {} // キーのみ、値のみ for key in dictionary.keys {} for values in dictionary.values {} コレクション
  • ディクショナリのコピー var a = [1:”a”, 2:”b”] var b = a // 値渡し a[1] = “z” // [1:”z”, 2:”b”] b // [1:”a”, 2:”b”] コレクション
  • if文 if 条件式 { /* Snip */ } else if 条件式 { /* Snip */ } コントロール
  • while文 while 条件式 { /* Snip */ } do { /* Snip */ } while 条件式 コントロール
  • for文 for var index = 0; index < 5; index++ { /* Snip */ } for index in 0..5 { /* Snip */ } コントロール
  • switch文 let foo = "hoge" switch foo { case "bar": println("bar") case "baz", "hoge": println("baz or hoge") default: println("other") } コントロール
  • switch文 基本 break 動作。 fallthrough を指定すると次の case も処理。 コントロール
  • switch文 いろいろなマッチング case 1...3: // Range case (_, 0): // tuple case (let x, 0): // value bindings case let (x, y) where x == y: // where コントロール
  • enum Fukuoka { case Tenjin case Daimyo case Hakata case Nakasu } 列挙型 (Enum)
  • 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 }
  • 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
  • enum Rank: Int { case One = 1 case Two, Three, Four } 列挙型 (Enum)
  • enum Rank: Int { case One = 1 case Two, Three, Four } var rank = Rank.Two // (Enum Value) 列挙型 (Enum)
  • enum Rank: Int { case One = 1 case Two, Three, Four } var rank = Rank.Two // (Enum Value) rank.toRaw() // 2 列挙型 (Enum)
  • 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)
  • enum Fukuoka: String { case Tenjin = "天神" case Hakata = "博多" } var city = Fukuoka.Hakata 列挙型 (Enum)
  • enum Fukuoka: String { case Tenjin = "天神" case Hakata = "博多" } var city = Fukuoka.Hakata city = .Tenjin // 型が分かっているので省略可能 列挙型 (Enum)
  • enum Fukuoka: String { case Tenjin = "天神" case Hakata = "博多" func toKana() -> String { switch self { case .Tenjin: return "てんじん" case .Hakata: return "はかた" } } } 列挙型 (Enum)
  • enum Fukuoka: String { case Tenjin = "天神" case Hakata = "博多" func toKana() -> String { switch self { case .Tenjin: return "てんじん" case .Hakata: return "はかた" } } } 列挙型 (Enum) var city = Fukuoka.Tenjin // 天神
  • 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() // てんじん
  • Associated Values enum APIResponse { case Success(Int, String) case Error(Int, String, NSError) } 列挙型 (Enum)
  • Associated Values enum APIResponse { case Success(Int, String) case Error(Int, String, NSError) } // if success var res = APIResponse.Success(200, “OK”) 列挙型 (Enum)
  • 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)
  • Associated Values switch res { case let .Success(httpStatus, message): … // 成功時処理 case let .Error(httpStatus, message, error): … // エラー処理 } 列挙型 (Enum)
  • 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)
  • func foo(bar: String, baz: Int) -> String {} 関数
  • func foo(bar: String, baz: Int) -> String {} // キーワード指定可 func foo(aaa bar: String, bbb baz: Int) -> String {} 関数
  • func foo(bar: String, baz: Int) -> String {} // キーワード指定可 func foo(aaa bar: String, bbb baz: Int) -> String {} // 引数のデフォルト値指定可 func foo(bar: String, baz: Int = 1) -> String {} 関数
  • // 引数の可変長指定可 (Variadic Parameter) func foo(bar: String, baz: Int...) -> String {} 関数
  • // 引数の可変長指定可 (Variadic Parameter) func foo(bar: String, baz: Int...) -> String {} // 引数の参照渡し (inoutラベル) func swapValue(inout a: Int, inout b: Int) {} swapValue(&a, &b) 関数
  • ネスト func foo() -> Int { func bar() { func baz() { } baz() } bar() } foo() 関数
  • 返り値が関数 func foo() -> ((Int, Int) -> String) { func bar(number: Int, number2: Int) -> String { return String(number + number2) } return bar } var bar = foo() bar(1,2) 関数
  • 返り値がタプル func getTuple() -> (Double, Int, String) { return (1.0, 2, "3") } var result = getTuple() result.0 // 1.0 result.1 // 2 result.2 // "3" 関数
  • 基本形 sort([“A”, “C”, “B”], { (s1: String, s2: String) -> Bool in return s1 < s2 }) // [“A”, “B”, “C”] クロージャ
  • 型推論が効く sort([“A”, “C”, “B”], { (s1: String, s2: String) -> Bool in return s1 < s2 }) ▼ sort([“A”, “C”, “B”], { s1, s2 in return s1 < s2 }) クロージャ
  • 式が1つだけの場合 return が省略できる sort([“A”, “C”, “B”], { s1, s2 in return s1 < s2 }) ▼ sort([“A”, “C”, “B”], { s1, s2 in s1 < s2 }) クロージャ
  • 引数をプレースホルダで置換できる sort([“A”, “C”, “B”], { s1, s2 in s1 < s2 }) ▼ sort([“A”, “C”, “B”], { $0 < $1 }) クロージャ
  • Operator Functions を使用する sort([“A”, “C”, “B”], { $0 < $1 }) ▼ sort([“A”, “C”, “B”], < ) クロージャ
  • Operator Functions を使用する sort([“A”, “C”, “B”], { $0 < $1 }) ▼ sort([“A”, “C”, “B”], < ) 式によってはここまで簡略化できる クロージャ
  • Trailing Closures sort([“A”, “C”, “B”], { $0 < $1 }) ▼ sort([“A”, “C”, “B”]) { $0 < $1 } クロージャ
  • Trailing Closures sort([“A”, “C”, “B”], { $0 < $1 }) ▼ sort([“A”, “C”, “B”]) { $0 < $1 } 引数の最後がクロージャの場合、外出し記述可 クロージャ
  • Trailing Closures sort([“A”, “C”, “B”], { $0 < $1 }) ▼ sort([“A”, “C”, “B”]) { $0 < $1 } 引数の最後がクロージャの場合、外出し記述可 sort([“A”, “C”, “B”]) { < } ※これはエラーになった クロージャ
  • blocks 内で self を使った場合の循環参照回避 // lang: Objective-C __weak BlockOwner *weakSelf = self; _block = ^() { NSLog(@"name: %@", weakSelf.name); }; クロージャ
  • blocks 内で self を使った場合の循環参照回避 // lang: Swift self.aProperty = { [unowned self] in // closure capture list self.doSomething() } クロージャ
  • blocks 内で self を使った場合の循環参照回避 // lang: Swift self.aProperty = { [unowned self] in // closure capture list self.doSomething() } 引き続き注意が必要 >< クロージャ
  • class Foo { var bar: String init(baz: Int) { // コンストラクタ self.bar = baz // propertyイニシャライズ必須 } func hoge(fuga: Int, piyo: Int) {} deinit {} // デストラクタ } クラス
  • コンストラクタ init() がコンストラクタ 引数がある場合 init(baz: Int) はインスタンス生成時に引数ラ ベルを指定する必要あり var foo = Foo(baz: 1) クラス
  • コンストラクタ init() がコンストラクタ 引数がある場合 init(baz: Int) はインスタンス生成時に引数ラ ベルを指定する必要あり var foo = Foo(baz: 1) ただし、_ をラベルにする事で回避できる init(_ bar:Int) // var foo = Foo(1) クラス
  • コンビニエンスコンストラクタ class Foo { var bar:Int init(baz: Int) { self.bar = baz } func hoge(fuga:Int, piyo:Int) {} convenience init() { self.init(baz:0) } } クラス
  • コンビニエンスコンストラクタ var foo = Foo() foo.bar // 0 コンストラクタ引数を省略する事ができる。その場合 convenience init 内に書かれた値で初期化される。 クラス
  • 継承 class Foo : Bar { } クラス
  • 継承 class Foo { } Objective-C と違い、基底クラスが無い場合は 継承を省略できる クラス
  • メソッドオーバーライド class Foo : Bar { override func baz() { } } クラス
  • メソッドオーバーライド class Foo : Bar { override func baz() { } } スーパークラスと同名のメソッドを定義していても、 override が無ければ別メソッドとして認識される クラス
  • コピー var foo1 = FooClass() foo1.bar // 10 var foo2 = foo1 foo2.bar // 10 クラス
  • コピー var foo1 = FooClass() foo1.bar // 10 var foo2 = foo1 foo2.bar // 10 foo1.bar = 50 foo2.bar // 50 クラス
  • コピー var foo1 = FooClass() foo1.bar // 10 var foo2 = foo1 // クラスは参照渡し foo2.bar // 10 foo1.bar = 50 foo2.bar // 50 クラス
  • コピー 値渡しでコピーしたい場合は、 import Foundation して NSCopying を継承。 copyWithZone() メソッドを自前で実装する。 (Objective-C と同じイメージ) via: http://qiita.com/taketin@github/items/abcd2bea9e5888afa141 クラス
  • 比較 (===) var foo1 = FooClass() var foo2 = FooClass() foo1 === foo2 // false クラス
  • 比較 (===) var foo1 = FooClass() var foo2 = FooClass() foo1 === foo2 // false var foo3 = foo1 foo3 === foo1 // true クラス
  • 比較 (===) var foo1 = FooClass() var foo2 = FooClass() foo1 === foo2 // false var foo3 = foo1 foo3 === foo1 // true インスタンスのアドレス比較を行う クラス
  • Getter, Setter class Foo { var bar: Int { get { return 10 } set { self.baz = newValue } } var baz: Int = 0 } クラス - プロパティ
  • Getter, Setter class Foo { var bar: Int { get { return 10 } set { self.baz = newValue } } var baz: Int = 0 } setter は “newValue” で新しい値を参照できる クラス - プロパティ
  • Getter, Setter class Foo { var bar: Int { get { return 10 } } var baz: Int = 0 } get のみ書く事で ReadOnly として定義できる クラス - プロパティ
  • willSet, didSet class Foo { var bar:Int { willSet {} didSet {} } } Objective-C の KVO のような動きができる クラス - プロパティ
  • 遅延ロード class Foo { @lazy var bar = SomeClass() } var foo = Foo() // ここでは bar 未初期化 foo.bar // ここで bar 初期化 クラス - プロパティ
  • Type Property Syntax class Foo { class var bar:Int { return 1 } } Foo.bar // 1 クラス - プロパティ
  • class Foo { var bar:Int = 5 init() {} subscript(index: Int) -> Int { return self.bar * index } } Subscript
  • class Foo { var bar:Int = 5 init() {} subscript(index: Int) -> Int { return self.bar * index } } var foo = Foo(); foo[10] // 50 オブジェクトへの添字アクセスができる Subscript
  • class Foo { var bar:Int = 5 init() {} subscript(index: Int) -> Int { get { /* Snip */ } set { /* Snip */ } } } アクセスコントロールも可能 Subscript
  • イニシャライズ struct Foo { var bar: Int = 1 func baz() -> String { return "test" } } var foo = Foo() 構造体 (Structure)
  • イニシャライズ struct Foo { var bar: Int func baz() -> String { return "test" } } var foo = Foo(bar: 1) 構造体 (Structure)
  • mutating struct Foo { var bar: Int = 1 func baz() { bar = 10 // コンパイルエラー } } 構造体 (Structure)
  • mutating struct Foo { var bar: Int = 1 mutating func baz() { bar = 10 } } 構造体 (Structure)
  • static variable struct Foo { static var bar: Int = 1 } Foo.bar // 1 構造体 (Structure)
  • コピー var foo1 = Foo() foo1.bar // 1 var foo2 = foo1 foo1.bar = 10 構造体 (Structure)
  • コピー var foo1 = Foo() foo1.bar // 1 var foo2 = foo1 foo1.bar = 10 foo2.bar // 1 構造体は値渡し(クラスは参照) 構造体 (Structure)
  • protocol FooProtocol { var bar: String { get } func baz() -> String } Protocol
  • protocol FooProtocol { var bar: String { get } func baz() -> String } class FooClass : FooProtocol { var bar: String = “hoge” func baz() -> String { /* Snip */ } } Protocol
  • protocol FooProtocol { var bar: String { get set } // getter, setter 必須 func baz() -> String } class FooClass : FooProtocol { var bar: String { get { /* Snip */ } // set が無いのでコンパイルエラー } Protocol
  • protocol FooProtocol { var bar: String mutating func baz() -> String } struct FooStruct : FooProtocol { var bar: String = “hoge” mutating func baz() -> String { /* Snip */ } } Protocol
  • protocol FooProtocol { } protocol BarProtocol { } class FooClass : FooProtocol, BarProtocol { /* Snip */ } 複数継承も可能 Protocol
  • extension String { func twice() -> String { return "(self) (self)" } } Extention
  • extension String { func twice() -> String { return "(self) (self)" } } var str = “hello” str.twice() // “hello hello” クラスだけでなく型などにも適用できる Extention
  • extension String : FooProtocol { func twice() -> String { return "(self) (self)" } } プロトコルの継承もできる Extention
  • func Foo <任意の型> () {} 型の形式は UpperCamelCase。<HogeType> など。 短く <T> 等が慣習的に使われている。 Generics
  • 型制約無し func repeat<T>(item: T, times: Int) -> T[] { var result = T[]() for i in 0..times { result += item } return result } Generics
  • 型制約無し 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
  • 型制約無し 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
  • 型制約有り func findIndex<T: Equatable>(array: T[], valueToFind: T) -> Int? { for (index, value) in enumerate(array) { if value == valueToFind { return index } } return nil } Generics
  • 型制約有り func findIndex<T: Equatable>(array: T[], valueToFind: T) -> Int? { for (index, value) in enumerate(array) { if value == valueToFind { return index } } return nil } プロトコル継承の制約を定義できる Generics
  • Any & AnyObject var array : Any[] = ["1", 2, Foo()] TypeCasting
  • Any & AnyObject // 関数型以外なんでも入れる事ができる var array : Any[] = ["1", 2, Foo()] TypeCasting
  • Any & AnyObject // 関数型以外なんでも入れる事ができる var array : Any[] = ["1", 2, Foo()] var array2 : AnyObject[] = [Foo(), Bar(), Baz()] TypeCasting
  • Any & AnyObject // 関数型以外なんでも入れる事ができる var array : Any[] = ["1", 2, Foo()] // クラスのインスタンスのみ入れる事ができる var array2 : AnyObject[] = [Foo(), Bar(), Baz()] TypeCasting
  • 型チェック 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
  • ダウンキャスト // obj には Base クラスのインスタンスが入っている // Base を継承した Bar クラスが定義されている let bar = obj as Bar // Bar クラス TypeCasting
  • ダウンキャスト // obj には Base クラスのインスタンスが入っている // Base を継承した Bar クラスが定義されている let bar = obj as Bar もし obj に Bar へダウンキャストできないオブジェクトが入って いたらランタイムエラー TypeCasting
  • ダウンキャスト // obj には Base クラスのインスタンスが入っている // Base を継承した Bar クラスが定義されている let bar = obj as? Bar オプショナルで安全 TypeCasting
  • ダウンキャスト 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 */ } }
  • ダウンキャスト 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 の評価式を使って、評価 > 代入が簡単に書ける
  • 存在する演算子を拡張 @infix func + (left: String, right: Int) -> String { return "(left) (right)" } Operator Functions
  • 存在する演算子を拡張 @infix func + (left: String, right: Int) -> String { return "(left) (right)" } “number” + 1 // “number 1” Operator Functions
  • 存在しない演算子を定義 @infix func +++ (left: String, right: Int) -> String { return "(left) (right)" } “number” +++ 1 Operator Functions
  • 存在しない演算子を定義 @infix func +++ (left: String, right: Int) -> String { return "(left) (right)" } “number” +++ 1 // コンパイルエラー Operator Functions
  • 存在しない演算子を定義 operator infix +++ {} @infix func +++ (left: String, right: Int) -> String { return "(left) (right)" } “number” +++ 1 // “number 1” Operator Functions
  • その他詳細は公式ドキュメントをご覧くだ さい。 https://developer.apple. com/library/prerelease/ios/documentation/swift/conceptual/swift_prog ramming_language/
  • ドキュメントに見当たりません おまけ:正規表現
  • えっ、、、 おまけ:正規表現
  • NSRegularExpression を利用して Perl ライクな =~ 演算子を使えるようにするライブラリがあるの でとりあえず利用すると良さそう。 https://github.com/kasei/SwiftRegex おまけ:正規表現
  • “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 おまけ:名前空間
  • アクセス修飾子 (private, public) おまけ:今後の展望
  • アクセス修飾子 (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 おまけ:今後の展望
  • CocoaPods おまけ:今後の展望
  • CocoaPods https://github.com/CocoaPods/CocoaPods/tree/swift https://github.com/CocoaPods/CocoaPods/pull/2222 着々と進行中の様です。待ちましょう。 おまけ:今後の展望
  • 汎用言語として公開してくれないかなー おまけ:今後の希望
  • LINE Fukuoka では Swift なら誰にも負けないと いうエンジニアさんを求めています! 更におまけ
  • 福岡で一緒に LINE を育てていきましょう! https://linefukuoka.co.jp/career/developer 更におまけ
  • ご清聴ありがとうございました。