25. いざやってみると…
• So many ? s...
• So many if let s...
• unexpectedly found nil while blabla...
💧
let result = try? NSJSONSerialization.JSONObjectWithData(…)
let name = ((result?["person"] as? [String: AnyObject])?
["name"] as? String)
if let name = name {
print("My name is: (name)")
}
思てたんと違う…
26. Swift とは…
• Swift は ObjC の「癖」を無くしただけの言語じゃない。
(Objective-C without the C ...? wtf)
• Swift に導入された新しいパラダイムをちゃんと理解しな
いと上手く書けない。
• さらに ObjC / Foundation への理解もないと、「なぜこ
うなっているのか」が分からないところがある。
• Swift には Swift の「癖」がある!
29. Objective-C の歴史
• 1983年に開発され、1985年に Apple社を去った Steve Jobs が
NeXT Computer 社を創立、その主力言語として採用される。
• 1997年、Apple社 が NeXT社 を買収し、2001年の Mac OS X
の Cocoaフレームワーク のコア言語として採用される。
• Foundation クラスの NS は OS名 NeXTSTEP 由来!
34. The Swift language … also greatly
benefited from the experiences hard-won
by many other languages in the field,
drawing ideas from Objective-C, Rust,
Haskell, Ruby, Python, C#, CLU, and far
too many others to list.
http://nondot.org/sabre/
Chris Lattner
37. Apple のドキュメントより
if let johnsStreet = john.residence?.address?.street {
print("John's street name is (johnsStreet).")
} else {
print("Unable to retrieve the address.")
}
Swift also introduces optional types, which handle the absence of a value.
Optionals say either “there is a value, and it equals x” or “there isn’t a value
at all”. Using optionals is similar to using nil with pointers in Objective-C,
but they work for any type, not just classes.
43. let maybeInt : Optional<Int> = .Some(1)
let actualInt = maybeInt!
let maybeInt : Optional<Int> = 1
let actualInt = maybeInt!
44. let maybeInt : Optional<Int> = .Some(1)
let actualInt = maybeInt!
let actualInt = maybeInt!
let maybeInt : Array<Int> = [1]
let actualInt = maybeInt[0]
こうだと思う
45. let maybeInt : Optional<Int> = nil
let actualInt = maybeInt!
// fatal error: unexpectedly found nil
while unwrapping an Optional value
let maybeInt : Array<Int> = []
let actualInt = maybeInt[0]
// fatal error: Array index out of range
nil は空配列みたいなモンなんだから、
中身を取り出そうとしたら怒られるに決まってる。
46. let maybeInt : Optional<Int> = .Some(1)
if let actualInt = maybeInt {
print("int: (actualInt)")
}
let maybeInt : Array<Int> = [1]
for actualInt in maybeInt {
print("int: (actualInt)")
}
if let は 1要素に対する for in と同じ!
(空なら for は回らないよネ)
49. とても不思議な guard let
let maybeInt: Optional = 1
guard let actualInt = maybeInt else {
fatalError()
}
print("value: (actualInt)")
50. とても不思議な guard let
let value: Optional = 1
guard let value = value else {
fatalError()
}
print("value: (value)")
unwrap した値を同じ変数に代入できる…
51. とても不思議な guard let
let value: Optional = 1
guard let value = value else {
fatalError()
}
print("value: (value)")
同じスコープ内で変数の型が変わってる…!!!
Optional<Int> 型
Int 型
59. let a = [2, 3, 1, 4] // [2, 3, 1, 4]
let b = a.map {$0 * 2} // [4, 6, 2, 8]
let c = b.filter {$0 < 5} // [4, 2]
map や filter を使いこなそう!
60. override func layoutAttributesForElementsInRect(rect: CGRect) ->
[UICollectionViewLayoutAttributes]? {
var result = [UICollectionViewLayoutAttributes]()
for i in 0 ..< items.count {
let indexPath = NSIndexPath(forItem: i, inSection: 0)
let attr = layoutAttributesForItemAtIndexPath(indexPath)
if attr.alpha == 0 {
continue
}
if !CGRectIntersectsRect(attr.frame, rect) {
continue
}
result.append(attr)
}
return result
}
map や filter を使うとループ処理が簡潔に書ける
before
63. let a : Optional = 1 // .Some(1)
let b = a.map { $0 * 2 } // .Some(2)
もちろん Optional に対しても map は使える
.Some(1) は [1] みたいなモンなんだから当たり前
64. let a : Optional = "1" // .Some("1")
let b = a.map { Int($0) } // .Some( .Some(1) )
let s : Optional = "hehe" // .Some("hehe")
let t = s.map { Int($0) } // .Some( .None )
map する関数が Optional を返す場合は
2重に包まれてしまう…
String -> Int は失敗する場合があるので Optional
65. let a : Optional = "1" // .Some("1")
let b = a.flatMap { Int($0) } // .Some(1)
let s : Optional = "hehe" // .Some("hehe")
let t = s.flatMap { Int($0) } // .nil
そういうときは flatMap !
66. let a = ["1", "2", "heh", "4", "lol"]
let b = a.flatMap{ Int($0) } // [1, 2, 4]
配列に Optional な戻り値を返す関数を
flatMap して filter みたいなこともできる
74. Swift の protocol とは…
• Java の interface のように型として扱えて、
• Scala の trait のように mix-in ができ、
• Haskell の type class のような AdHoc ポリ
モーフィズムが実現できる素晴らしい仕組み!
75. Haskell の「型クラス」
class Eq a where
(==), (/=) :: a -> a -> Bool
x == y = not (x /= y)
x /= y = not (x == y)
data Point = Pt Double Double
instance Eq Point where
(Pt x y) == (Pt x' y') = x == x' && y == y'
Eq クラス
Point 型を Eq クラスのインスタンスに
http://walk.wgag.net/haskell/typeclass.html より
76. そっくり!
public protocol Equatable {
public func ==(lhs: Self, rhs: Self) -> Bool
}
struct Point: Equatable {
let x, y: Double
}
func ==(p1: Point, p2: Point) -> Bool {
return p1.x == p2.x && p1.y == p2.y
}
Equatable プロトコル
Point 型を Equatable に適合
80. protocol MyProtocol: Equatable {}
struct A: MyProtocol {}
struct B: MyProtocol {}
let a: [MyProtocol] = [A(), B()]
// protocol 'MyProtocol' can only be used
as a generic constraint because it has
Self or associated type requirements