ݺߣ

ݺߣShare a Scribd company logo
My Sweet Swift
Agenda 
? Generics 
? Enumeration 
? Optional 
? Appendix
Agenda 
? Generics 
? Enumeration 
? Optional 
? Appendix 
}ʂ 
}
Generics
Generics 
? ͤѥ`ˤȤv?ǩ` 
? 򱣤äޤޡ}ͤͬrˌ 
Ǥ 
? Ȥϣ
: 򤽤Τޤ޷v 
func identity(input: Int) -> Int { 
return input 
} 
! 
let number = identity(42) // Int 
let string = identity("Lorem ipusm") // error
: 򤽤Τޤ޷v 
func identity(input: Any) -> Any { 
return input 
} 
! 
let number = identity(42) // Any 
let string = identity("Lorem ipsum") // Any 
! 
number * 2 // error 
string + string // error
: 򤽤Τޤ޷v 
func identity<T>(input: T) -> T { 
return input 
} 
! 
let number = identity(42) // Int 
let string = identity("Lorem ipsum") // String 
! 
number * 2 
string + string
: map 
x 
f 
"(x)" 
func f(x: Int) -> String { 
return "(x)" 
}
: map 
x [1, 2, 3] 
f 
"(x)"
: map 
x [1, 2, 3] 
f 
"(x)" ["1", "2", "3"]
: map 
x [1, 2, 3] 
f 
"(x)" ["1", "2", "3"] 
map([Int], Int -> String) -> [String]
: map 
func f(x: Int) -> String { 
return "(x)" 
} 
! 
func map(xs: [Int], f: Int -> String) -> [String] { 
var ys = [String]() 
for x in xs { 
ys.append(f(x)) 
} 
return ys 
} 
! 
map([1, 2, 3], f) // ["1", "2", 3"] 
map([1, 2, 3], { "($0)" }) // ["1", "2", "3"]
: map 
Int [Int] 
f 
String [String] 
map([Int], Int -> String) -> [String]
: map 
T [T] 
T -> U 
U [U] 
map([T], T -> U) -> [U]
: map 
func map<T, U>(xs: [T], f: T -> U) -> [U] { 
var ys = [U]() 
for x in xs { 
ys.append(f(x)) 
} 
return ys 
} 
! 
// [Int] -> [String] 
map([1, 2, 3], { "($0)" }) // ["1", "2", "3"] 
// [Int] -> [Double] 
map([1, 2, 3], { $0 * 2.0 }) // [2.0, 4.0, 6.0] 
// [Double] -> [CGRect] 
map([1, 2, 3], { CGRect(x: $0, y: $0, width: 100.0, height: 100.0) })
饹: Stack 
class Stack<T> { 
private var array = [T]() 
func push(item: T) { 
array.append(item) 
} 
func pop() -> T { 
return array.removeLast() 
} 
} 
! 
let stack = Stack<Int>() 
stack.push(1) 
stack.push(2) 
stack.push(3) 
stack.pop() // 3 
stack.pop() // 2 
stack.pop() // 1
Enumerations
Enums 
enum BloodType { 
case A, B, O, AB 
} 
! 
struct Person { 
var bloodType: BloodType 
} 
! 
var p = Person(bloodType: BloodType.A) 
var q = Person(bloodType: .A) 
q.bloodType = .AB
Enums 
? ObjCEnum`äơ֤ʤ 
? ex. |ϱ굱Ƥζ 
? ͨ˂֤뤳ȤǤ 
? ФOK
with associated values 
/// UIҪؤָenum 
enum DialogItem { 
case TextButton(title: String, identifier: String) 
case GrayButton(title: String, identifier: String) 
case Text(String) 
case Title(String) 
case Margin(CGFloat) 
case Group([DialogItem]) 
} 
! 
let item1 = DialogItem.Margin(20) 
let item2 = DialogItem.Text("String")
Associated Values 
? enumθ״B˂~Ť뤳ȤǤ 
? ͤ`äƤƤ⤤ 
? gʤВȤϡ}ͤΤɤ 
ͤˤʤ
Switchǂչ_ 
switch item { 
case let .Title(title): 
println("Title: (title)") 
case let .Text(text): 
println("Text: (text)") 
case let .TextButton(title: title, identifier: identifier): 
/// 
case let .GrayButton(title: title, identifier: identifier): 
/// 
case let .Group(subitems): 
/// 
default: break 
}
: DialogViewController 
let items: [DialogViewController.DialogItem] = [ 
.Title(""), 
.Text("ʾҪؤФǶɤǡڤ˥뤳ȤǤޤ"), 
.TextButton(title: "ܥ", identifier: "button1"), 
.Margin(60), 
.Group([ 
.Group([.Text("νM"), .Text("ˤ")]), 
.Group([.Text(""), .Text("֤")]) 
]), 
.Group([ 
.TextButton(title: "ܥ", identifier: "button2"), 
.GrayButton(title: "ܥ", identifier: "button3"), 
.TextButton(title: "ܥ", identifier: "button4") 
]) 
] 
let dialog = DialogViewController(items: items, callback: nil) 
presentViewController(dialog, animated: true, completion: nil)
g: Failable 
? ʧ뤫⤷ʤYӛ 
? ʧFailedɹSucceeded 
? ɹϤϽYAssociated Value˳
: Failable<T> 
enum Failable<T> { 
case Succeeded(T) // ɹȤ΂ 
case Failed // ʧե饰 
init(_ value: T) { 
self = .Succeeded(value) 
} 
}
: Failable<T> 
// Ǹ줿뤱ɸʤä餢루ݤΤʤv 
func failableHalve(x: Int) -> Failable<Int> { 
if x % 2 == 0 { 
return .Succeeded(x / 2) 
} else { 
return .Failed 
} 
} 
! 
switch failableHalve(12) { 
case let .Succeeded(r): 
println("Answer: (r)") 
default: 
println("Odd Number") 
}
ä 
// Ǹ줿뤱ɸʤä餢루ݤΤʤv 
func failableHalve(x: Int) -> Optional<Int> { 
if x % 2 == 0 { 
return .Some(x / 2) 
} else { 
return .None 
} 
} 
! 
switch failableHalve(12) { 
case let .Some(r): 
println("Answer: (r)") 
default: 
println("Odd Number") 
}
OptionalʤΤǤϣ 
// Ǹ줿뤱ɸʤä餢루ݤΤʤv 
func failableHalve(x: Int) -> Int? { 
if x % 2 == 0 { 
return x / 2 
} else { 
return nil 
} 
} 
!! 
if let r = failableHalve(12) { 
println("Answer: (r)") 
} else { 
println("Odd Number") 
}
Optional
̫ŤԳܱˡषƤ
Optionalǰ 
? ֥ȤȤϥݥ󥿤Ǥ 
? ؄eʥɥ쥹यΈ0NULLȺ 
ӡָݥ󥿤򡸟oʥ֥ 
ȡȤƒQ
} 
? NULLoʂ֪äƤΤόgФΥ 
ȥץޤ 
? ѥˤΥݥ󥿂eǤʤ 
? gЕr 
? ڤNULLzޤʤ褦ˡݤĤ 
롹_J롹ȤǤʤä
OptionalΤȤ 
? oʂȤͤˤȤǡ 
ζՓǤϤʤՓȤƒQ 
? oʂQʤķ
Optional<T> 
enum Optional<T> : Reflectable, NilLiteralConvertible { 
case None 
case Some(T) 
! 
/// Construct a `nil` instance. 
init() 
! 
/// Construct a non- `nil` instance that stores `some`. 
init(_ some: T) 
! 
/// If `self == nil`, returns `nil`. Otherwise, returns `f(self!)`. 
func map<U>(f: (T) -> U) -> U? 
! 
/// Returns a mirror that reflects `self`. 
func getMirror() -> MirrorType 
! 
/// Create an instance initialized with `nil`. 
init(nilLiteral: ()) 
}
Optional<T> 
? gGeneric Enum 
? gϤäǡ؄eQܤƤ 
? cf. http://qiita.com/koher/items/ 
5dd6ce7427e7ecff4249 
? Failable<T>ͬ褦ˣǤ
Optional as  
? T⤷ʤǤϤʤT䡹 
? ˴뤿ˤ_Ҫ 
? binding/coalescing/unwrapping 
? _˲뷽⤢ 
? mapping/chaining
Optional Binding 
var optionalInt: Int? 
! 
if let int = optionalInt { // int: Int 
println("optionalInt was (int)") 
} else { 
println("optionalInt was nil") 
} 
! 
var array = [1, 2, 3, 4] 
while let item = array.last { // item: Int 
println("(item)") 
array.removeLast() 
}
_: Optional Binding 
? trueuĤ 
`bindƤ 
? һȤһbindǤʤΤ϶ٲ
Optional Coalescing 
optionalInt ?? 3 
! 
// ȵȁ 
optionalInt != nil ? optionalInt! : 3 
! 
// 뤤ϣ 
func coalesce<T>(lhs: T?, rhs: @autoclosure () -> T) -> T { 
if let lhs = lhs { 
return lhs 
} else { 
return rhs() 
} 
} 
coalesce(optionalInt, 3)
_: Optional Coalescing 
? _줿_ 
? _ʤä_ʤ 
? ˥ǥեȂ򷵤
oʸ_: Forced Unwrapping 
optionalInt! 
? Ф줬뤬ʤ 
? ԤΤʹ٤ǤϤʤ 
? ȫ^Ǥʤ阋ʤ
䤫M뷽 
? Optional mapping 
? Optional chaining
Optional Mapping 
/// v 
func triple(x: Int) -> Int { 
return x * 3 
} 
! 
optionalInt = 2 
// ¤Ϥ٤.Some 6 
optionalInt.map(triple) 
map(optionalInt, triple) 
optionalInt.map({ $0 * 3 })
_ʤ: Optional Mapping 
? ФeФ 
? ФƤƄe䣨Optional 
 
? nilʤnil򷵤
Optional Mapping 
T 
U 
T -> U 
T? 
U? 
map(T?, T -> U) -> U?
Optional Chaining 
class A { 
var b: B? 
} 
! 
class B { 
var c: C? 
} 
! 
class C { 
var i: Int = 1 
} 
var a: A? = A() 
// a.b.c.i˥
Optional Chaining 
var a: A? 
! 
if let a = a { 
if let b = a.b { 
if let c = b.c { 
println("We finally find (c.i)!") 
} 
} 
}
Optional Chaining 
var a: A? 
! 
if let i = a?.b?.c?.i { 
println("Optional chaining makes (i)t easy.") 
}
_ʤ: Optional Chaining 
? ʧ뤫⤷ʤӳBiǤ 
? ʧФȤˤMޤnil
Optional Chaining 
a?.b?.c?.i 
A? 
aA?ͤΉ
 
Optional Chaining 
a.b 
A? 
A?ͤbȤФϤʤ
Optional Chaining 
a?.b?.c?.i 
A? 
a?.bȤΤˤ
Optional Chaining 
a?.b?.c?.i 
A() 
or 
nil 
anilSomeΤɤ餫
Optional Chaining 
a?.b?.c?.i 
A() 
B? 
or 
nil 
Someʤb˴
Optional Chaining 
a?.b?.c?.i 
A() 
B? 
or 
nil nil 
nilʤ餽ǽK
Optional Chaining 
a?.b?.c?.i 
A() 
B? 
or 
nil nil 
bB?ͤΉ
Optional Chaining 
a?.b?.c?.i 
A() 
B() 
C? 
or 
or 
nil nil 
nil 
ͬ褦˷
Optional Chaining 
a?.b?.c?.i 
A() 
B() 
C() 
7 
or 
or 
or 
nil nil 
nil 
nil 
ͬ
ֱƤߤ 
extension Optional { 
func chain<U>(f: T -> U?) -> U? { 
if let s = self { 
return f(s) 
} else { 
return nil 
} 
} 
} 
! 
if let i = a.chain({ $0.b }).chain({ $0.c }).chain({ $0.i }) { 
println("(i)") 
} 
! 
// _ˤϡhʡԣYϵȤʤ룩 
// let k = a.chain({ $0.b.chain({ $0.c.chain({ $0.i }) }) })
ʤֱΣ 
? vˤʹ褦ˤ 
? 줬դۤǤ
Failable Halve 
Int Int? 
// Ǹ줿뤱ɸʤä餢루ݤΤʤv 
func failableHalve(x: Int) -> Int? { 
if x % 2 == 0 { 
return x / 2 
} else { 
return nil 
} 
} 
! 
if let a = failableHalve(x) { 
println("Halve((x)) = (a)") 
} else { 
println("Failed") 
}
Failable Halve Again 
Int Int? 
if let a = failableHalve(x) { 
if let b = failableHalve(a) { 
println("Halve^2((x)) = (b)") 
} else { 
println("Failed") 
} 
} else { 
println("Failed") 
} 
Int Int?
Failable Halve The 3rd 
Int Int? 
if let a = failableHalve(x) { 
if let b = failableHalve(a) { 
if let c = failableHalve(b) { 
println("Halve^3((x)) = (c)") 
} else { 
println("Failed") 
} 
} else { 
println("Failed") 
} 
} else { 
println("Failed") 
} 
Int Int? Int Int?
Failable Halve Chaining 
Int Int? 
if let a = failableHalve(x).chain(failableHalve).chain(failableHalve) { 
println("Halve^3((x)) = (a)") 
} else { 
println("Failed") 
} 
Int? Int?
Failable Halve Chaining 
Int Int? 
Int? Int? 
24 
failableHalve(24) // Some 12 
failableHalve(24).chain(failableHalve) // Some 6 
failableHalve(24).chain(failableHalve).chain(failableHalve) // Some 3 
failableHalve(24).chain(failableHalve).chain(failableHalve).chain(failableHalve) // nil 
! 
36 
failableHalve(36) // Some 18 
failableHalve(36).chain(failableHalve) // Some 9 
failableHalve(36).chain(failableHalve).chain(failableHalve) // nil 
failableHalve(36).chain(failableHalve).chain(failableHalve).chain(failableHalve) // nil
Optional Chaining 
t: T 
T
Optional Chaining 
T f U? 
f(t): U?
Optional Chaining 
U g V? 
T f U? 
f(t): U?
Optional Chaining 
g 
f V? 
T U? 
f(t).chain(g): V?
Optional Chaining 
g 
V h W? 
f V? 
T U? 
f(t).chain(g): V?
Optional Chaining 
g h W? 
f V? 
T U? 
f(t).chain(g).chain(h): W?
Appendix
Array Mapping 
T [T] 
T -> U 
U [U] 
map([T], T -> U) -> [U]
Optional Mapping 
T 
U 
T -> U 
T? 
U? 
map( T?, T -> U) -> U?
Optional<T>Array<T> 
? Tͤ΂ä 
? mapʹдȤǤ
Optional as ״r 
? ȤǡOptionalϡnil⤷ʤ 
״rcontextFƤ 
? ArrayϤɤ״rFƤ룿 
? _Ƥʤ
Array as ״r 
Kyoto
ĿȾˤ 
(0, 0) 
Kyoto
i 
(0, 1) 
(-1,0) (1, 0) 
(0,-1) 
Kyoto
i 
///  
typealias Position = (Int, Int) 
! 
/// |ϱΤɤؚiޤ 
func walk(from: Position) -> [Position] { 
let (x, y) = from 
return [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)] 
} 
! 
walk((0, 0)) // [(-1, 0), (1, 0), (0, -1), (0, 1)]
˚i 
Kyoto
˚i 
Kyoto
Array Chaining 
T [U] 
U 
[V] 
V [W]
Array Chaining 
extension Array { 
func chain<U>(f: Element -> [U]) -> [U] { 
var ys = [U]() 
for x in self { 
ys += f(x) 
} 
return ys 
} 
} 
! 
walk((0, 0)).chain(walk).chain(walk)
ä״r 
? ͬڤǷäƤ롹״r
20141128 iOS`㏊ My Sweet Swift
BFTask 
doHeavyJobAsync1().continueWithBlock { 
(task: BFTask!) -> BFTask in 
let result = task.result as NSString 
self.resultLabel1.text = result 
self.resultLabel2.text = "I..." 
return self.doHeavyJobAsync2(result) 
}.continueWithBlock { 
(task: BFTask!) -> BFTask in 
let result = task.result as NSString 
self.resultLabel2.text = result 
self.resultLabel3.text = "I..." 
return self.doHeavyJobAsync3(result) 
}.continueWithBlock { 
(task: BFTask!) -> AnyObject! in 
let result = task.result as NSString 
self.resultLabel3.text = result 
return nil 
}
BFTask 
private func doHeavyJobAsync2(prevResult: String) -> BFTask { 
var completionSource = BFTaskCompletionSource() 
// 5΄I 
// gõĤˤϡAFNetworkingcompletion֥åȤsetResult륤` 
Util.delay(5, { 
completionSource.setResult(prevResult + "???") 
}) 
return completionSource.task 
}
Task<T> 
class Task<T: AnyObject> { 
private let task: BFTask 
! 
init(task: BFTask) { 
self.task = task 
} 
var result: T? { 
return task.result as? T 
} 
func chain<U: AnyObject>(f: (T -> Task<U>)) -> Task<U> { 
let newTask = task.continueWithBlock { f($0.result as T).task } 
return Task<U>(task: newTask) 
} 
}
Task򷵤v 
private func doHeavyJobAsync2(prevResult: NSString) -> Task<NSString> { 
let source = Source<NSString>() 
// 5΄I 
// gõĤˤϡAFNetworkingcompletion֥åȤsetResult륤` 
delay(5, { 
source.setResult(prevResult + "???" as NSString) 
}) 
return source.task 
}
Task Chaining 
T U 
U 
V 
V W 
ͬ 
ͬ 
ͬ
Task Chaining 
func heavyTask1(Void) -> Task<NSString> { 
return delayedTask(5) { 
NSLog("First Task (no params)") 
return "123" as NSString 
} 
} 
! 
func heavyTask2(string: NSString) -> Task<NSNumber> { 
return delayedTask(5) { 
NSLog("Second Task (param: (string))") 
return NSNumber(integer: (string as String).toInt() ?? 0) 
} 
} 
! 
func heavyTask3(number: NSNumber) -> Task<NSNumber> { 
return delayedTask(5) { 
NSLog("Third Task (param: (number))") 
return NSNumber(integer: number.integerValue * 2) 
} 
}
Task Chaining 
NSLog("Start") 
heavyTask1().chain(heavyTask2).chain(heavyTask3) 
NSLog("End") 
2014-11-27 21:15:24.659 MySweetSwift[18362:314049] Start 
2014-11-27 21:15:24.663 MySweetSwift[18362:314049] End 
2014-11-27 21:15:29.663 MySweetSwift[18362:314049] First Task (no params) 
2014-11-27 21:15:35.136 MySweetSwift[18362:314049] Second Task (param: 123) 
2014-11-27 21:15:40.636 MySweetSwift[18362:314049] Third Task (param: 123)
ޤȤ 
? OptionalϤ襤 
? ArrayOptionalƤƤ 
? ʤǤꡢ״rǤ 
? ͬڄIͬ褦Ҋ뤳ȤǤ 
? Optional ChainingΤ褦ʕǤơ 
BFTaskƤƤ
ο

More Related Content

What's hot (20)

Haskell Lecture 2
Haskell Lecture 2Haskell Lecture 2
Haskell Lecture 2
Yusuke Matsushita
?
쳾ٳǿk
쳾ٳǿk쳾ٳǿk
쳾ٳǿk
r
?
񤫤ʼ Lens/Prism
񤫤ʼ Lens/Prism񤫤ʼ Lens/Prism
񤫤ʼ Lens/Prism
Naoki Aoyama
?
Van laarhoven lens
Van laarhoven lensVan laarhoven lens
Van laarhoven lens
Naoki Aoyama
?
vͥץߥT with OCaml
vͥץߥT with OCamlvͥץߥT with OCaml
vͥץߥT with OCaml
Haruka Oikawa
?
HaskellSѧܤ 6
HaskellSѧܤ 6HaskellSѧܤ 6
HaskellSѧܤ 6
aomori ringo
?
Real World OCamliLispȅf{Ƥߤ
Real World OCamliLispȅf{ƤߤReal World OCamliLispȅf{Ƥߤ
Real World OCamliLispȅf{Ƥߤ
blackenedgold
?
vץߥ
vץߥvץߥ
vץߥ
Hideyuki Tanaka
?
Scala vͥ??ߥ?֧뼼g
Scala vͥ??ߥ?֧뼼gScala vͥ??ߥ?֧뼼g
Scala vͥ??ߥ?֧뼼g
Naoki Aoyama
?
᥿ץߥ C#
᥿ץߥ C#᥿ץߥ C#
᥿ץߥ C#
Fujio Kojima
?
F#T vץߥ󥰤ȤϺΤ
F#T vץߥ󥰤ȤϺΤF#T vץߥ󥰤ȤϺΤ
F#T vץߥ󥰤ȤϺΤ
Nobuhisa Koizumi
?
ɾڳ٤餤
ɾڳ٤餤ɾڳ٤餤
ɾڳ٤餤
Hidenori Takeshita
?
C# ʽľ (Expression Tree) LINQ⤹뤿
C# ʽľ (Expression Tree)  LINQ⤹뤿 C# ʽľ (Expression Tree)  LINQ⤹뤿
C# ʽľ (Expression Tree) LINQ⤹뤿
Fujio Kojima
?
MP in Scala
MP in ScalaMP in Scala
MP in Scala
Kent Ohashi
?
Scala with DDD
Scala with DDDScala with DDD
Scala with DDD
һ
?
줫 Haskell ˤä
줫 Haskell ˤä줫 Haskell ˤä
줫 Haskell ˤä
Tsuyoshi Matsudate
?
Τ߽v
Τ߽vΤ߽v
Τ߽v
Shinichi Kozake
?
Actor&stm
Actor&stmActor&stm
Actor&stm
һ
?
MP in Haskell
MP in HaskellMP in Haskell
MP in Haskell
Kent Ohashi
?

Similar to 20141128 iOS`㏊ My Sweet Swift (20)

Implicit Explicit Scala
Implicit Explicit ScalaImplicit Explicit Scala
Implicit Explicit Scala
Kota Mizushima
?
ץߥ󥰤Τΰ++
ץߥ󥰤Τΰ++ץߥ󥰤Τΰ++
ץߥ󥰤Τΰ++
natrium11321
?
How wonderful to be (statically) typed ?ͤäƥХ饷?
How wonderful to be (statically) typed ?ͤäƥХ饷?How wonderful to be (statically) typed ?ͤäƥХ饷?
How wonderful to be (statically) typed ?ͤäƥХ饷?
Hiromi Ishii
?
TypeScript 1.0 `Щ`ӥ`
TypeScript 1.0 `Щ`ӥ`TypeScript 1.0 `Щ`ӥ`
TypeScript 1.0 `Щ`ӥ`
Akira Inoue
?
ʲٳDzԤʼٰDZdz洡ʱ
ʲٳDzԤʼٰDZdz洡ʱʲٳDzԤʼٰDZdz洡ʱ
ʲٳDzԤʼٰDZdz洡ʱ
Daisuke Igarashi
?
Τv
ΤvΤv
Τv
Shinichi Kozake
?
Clojure programming-chapter-2
Clojure programming-chapter-2Clojure programming-chapter-2
Clojure programming-chapter-2
Masao Kato
?
Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3
Ransui Iso
?
C++0x in programming competition
C++0x in programming competitionC++0x in programming competition
C++0x in programming competition
yak1ex
?
Python standard 2022 Spring
Python standard 2022 SpringPython standard 2022 Spring
Python standard 2022 Spring
anyakichi
?
ˤͰȫʥ`ϥ??
ˤͰȫʥ`ϥ??ˤͰȫʥ`ϥ??
ˤͰȫʥ`ϥ??
TanUkkii
?
Boost jp9 program_options
Boost jp9 program_optionsBoost jp9 program_options
Boost jp9 program_options
nyaocat
?
٤ʤХޥեʤ - 󥿩`Щ`-
٤ʤХޥեʤ - 󥿩`Щ`-٤ʤХޥեʤ - 󥿩`Щ`-
٤ʤХޥեʤ - 󥿩`Щ`-
Kazunari Hara
?
ʥɥϥ󥺥ǰ
ʥɥϥ󥺥ǰʥɥϥ󥺥ǰ
ʥɥϥ󥺥ǰ
bleis tift
?
Υץީ`ǤդʹJavaScriptgץ
Υץީ`ǤդʹJavaScriptgץ  Υץީ`ǤդʹJavaScriptgץ
Υץީ`ǤդʹJavaScriptgץ
schoowebcampus
?
ٲܳٱǰdzٱԤϤ褦
ٲܳٱǰdzٱԤϤ褦ٲܳٱǰdzٱԤϤ褦
ٲܳٱǰdzٱԤϤ褦
Shinsuke Sugaya
?
How wonderful to be (statically) typed ?ͤäƥХ饷?
How wonderful to be (statically) typed ?ͤäƥХ饷?How wonderful to be (statically) typed ?ͤäƥХ饷?
How wonderful to be (statically) typed ?ͤäƥХ饷?
Hiromi Ishii
?
TypeScript 1.0 `Щ`ӥ`
TypeScript 1.0 `Щ`ӥ`TypeScript 1.0 `Щ`ӥ`
TypeScript 1.0 `Щ`ӥ`
Akira Inoue
?
Clojure programming-chapter-2
Clojure programming-chapter-2Clojure programming-chapter-2
Clojure programming-chapter-2
Masao Kato
?
Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3
Ransui Iso
?
C++0x in programming competition
C++0x in programming competitionC++0x in programming competition
C++0x in programming competition
yak1ex
?
Python standard 2022 Spring
Python standard 2022 SpringPython standard 2022 Spring
Python standard 2022 Spring
anyakichi
?
ˤͰȫʥ`ϥ??
ˤͰȫʥ`ϥ??ˤͰȫʥ`ϥ??
ˤͰȫʥ`ϥ??
TanUkkii
?
Boost jp9 program_options
Boost jp9 program_optionsBoost jp9 program_options
Boost jp9 program_options
nyaocat
?
٤ʤХޥեʤ - 󥿩`Щ`-
٤ʤХޥեʤ - 󥿩`Щ`-٤ʤХޥեʤ - 󥿩`Щ`-
٤ʤХޥեʤ - 󥿩`Щ`-
Kazunari Hara
?
Υץީ`ǤդʹJavaScriptgץ
Υץީ`ǤդʹJavaScriptgץ  Υץީ`ǤդʹJavaScriptgץ
Υץީ`ǤդʹJavaScriptgץ
schoowebcampus
?

20141128 iOS`㏊ My Sweet Swift

  • 2. Agenda ? Generics ? Enumeration ? Optional ? Appendix
  • 3. Agenda ? Generics ? Enumeration ? Optional ? Appendix }ʂ }
  • 5. Generics ? ͤѥ`ˤȤv?ǩ` ? 򱣤äޤޡ}ͤͬrˌ Ǥ ? Ȥϣ
  • 6. : 򤽤Τޤ޷v func identity(input: Int) -> Int { return input } ! let number = identity(42) // Int let string = identity("Lorem ipusm") // error
  • 7. : 򤽤Τޤ޷v func identity(input: Any) -> Any { return input } ! let number = identity(42) // Any let string = identity("Lorem ipsum") // Any ! number * 2 // error string + string // error
  • 8. : 򤽤Τޤ޷v func identity<T>(input: T) -> T { return input } ! let number = identity(42) // Int let string = identity("Lorem ipsum") // String ! number * 2 string + string
  • 9. : map x f "(x)" func f(x: Int) -> String { return "(x)" }
  • 10. : map x [1, 2, 3] f "(x)"
  • 11. : map x [1, 2, 3] f "(x)" ["1", "2", "3"]
  • 12. : map x [1, 2, 3] f "(x)" ["1", "2", "3"] map([Int], Int -> String) -> [String]
  • 13. : map func f(x: Int) -> String { return "(x)" } ! func map(xs: [Int], f: Int -> String) -> [String] { var ys = [String]() for x in xs { ys.append(f(x)) } return ys } ! map([1, 2, 3], f) // ["1", "2", 3"] map([1, 2, 3], { "($0)" }) // ["1", "2", "3"]
  • 14. : map Int [Int] f String [String] map([Int], Int -> String) -> [String]
  • 15. : map T [T] T -> U U [U] map([T], T -> U) -> [U]
  • 16. : map func map<T, U>(xs: [T], f: T -> U) -> [U] { var ys = [U]() for x in xs { ys.append(f(x)) } return ys } ! // [Int] -> [String] map([1, 2, 3], { "($0)" }) // ["1", "2", "3"] // [Int] -> [Double] map([1, 2, 3], { $0 * 2.0 }) // [2.0, 4.0, 6.0] // [Double] -> [CGRect] map([1, 2, 3], { CGRect(x: $0, y: $0, width: 100.0, height: 100.0) })
  • 17. 饹: Stack class Stack<T> { private var array = [T]() func push(item: T) { array.append(item) } func pop() -> T { return array.removeLast() } } ! let stack = Stack<Int>() stack.push(1) stack.push(2) stack.push(3) stack.pop() // 3 stack.pop() // 2 stack.pop() // 1
  • 19. Enums enum BloodType { case A, B, O, AB } ! struct Person { var bloodType: BloodType } ! var p = Person(bloodType: BloodType.A) var q = Person(bloodType: .A) q.bloodType = .AB
  • 20. Enums ? ObjCEnum`äơ֤ʤ ? ex. |ϱ굱Ƥζ ? ͨ˂֤뤳ȤǤ ? ФOK
  • 21. with associated values /// UIҪؤָenum enum DialogItem { case TextButton(title: String, identifier: String) case GrayButton(title: String, identifier: String) case Text(String) case Title(String) case Margin(CGFloat) case Group([DialogItem]) } ! let item1 = DialogItem.Margin(20) let item2 = DialogItem.Text("String")
  • 22. Associated Values ? enumθ״B˂~Ť뤳ȤǤ ? ͤ`äƤƤ⤤ ? gʤВȤϡ}ͤΤɤ ͤˤʤ
  • 23. Switchǂչ_ switch item { case let .Title(title): println("Title: (title)") case let .Text(text): println("Text: (text)") case let .TextButton(title: title, identifier: identifier): /// case let .GrayButton(title: title, identifier: identifier): /// case let .Group(subitems): /// default: break }
  • 24. : DialogViewController let items: [DialogViewController.DialogItem] = [ .Title(""), .Text("ʾҪؤФǶɤǡڤ˥뤳ȤǤޤ"), .TextButton(title: "ܥ", identifier: "button1"), .Margin(60), .Group([ .Group([.Text("νM"), .Text("ˤ")]), .Group([.Text(""), .Text("֤")]) ]), .Group([ .TextButton(title: "ܥ", identifier: "button2"), .GrayButton(title: "ܥ", identifier: "button3"), .TextButton(title: "ܥ", identifier: "button4") ]) ] let dialog = DialogViewController(items: items, callback: nil) presentViewController(dialog, animated: true, completion: nil)
  • 25. g: Failable ? ʧ뤫⤷ʤYӛ ? ʧFailedɹSucceeded ? ɹϤϽYAssociated Value˳
  • 26. : Failable<T> enum Failable<T> { case Succeeded(T) // ɹȤ΂ case Failed // ʧե饰 init(_ value: T) { self = .Succeeded(value) } }
  • 27. : Failable<T> // Ǹ줿뤱ɸʤä餢루ݤΤʤv func failableHalve(x: Int) -> Failable<Int> { if x % 2 == 0 { return .Succeeded(x / 2) } else { return .Failed } } ! switch failableHalve(12) { case let .Succeeded(r): println("Answer: (r)") default: println("Odd Number") }
  • 28. ä // Ǹ줿뤱ɸʤä餢루ݤΤʤv func failableHalve(x: Int) -> Optional<Int> { if x % 2 == 0 { return .Some(x / 2) } else { return .None } } ! switch failableHalve(12) { case let .Some(r): println("Answer: (r)") default: println("Odd Number") }
  • 29. OptionalʤΤǤϣ // Ǹ줿뤱ɸʤä餢루ݤΤʤv func failableHalve(x: Int) -> Int? { if x % 2 == 0 { return x / 2 } else { return nil } } !! if let r = failableHalve(12) { println("Answer: (r)") } else { println("Odd Number") }
  • 32. Optionalǰ ? ֥ȤȤϥݥ󥿤Ǥ ? ؄eʥɥ쥹यΈ0NULLȺ ӡָݥ󥿤򡸟oʥ֥ ȡȤƒQ
  • 33. } ? NULLoʂ֪äƤΤόgФΥ ȥץޤ ? ѥˤΥݥ󥿂eǤʤ ? gЕr ? ڤNULLzޤʤ褦ˡݤĤ 롹_J롹ȤǤʤä
  • 34. OptionalΤȤ ? oʂȤͤˤȤǡ ζՓǤϤʤՓȤƒQ ? oʂQʤķ
  • 35. Optional<T> enum Optional<T> : Reflectable, NilLiteralConvertible { case None case Some(T) ! /// Construct a `nil` instance. init() ! /// Construct a non- `nil` instance that stores `some`. init(_ some: T) ! /// If `self == nil`, returns `nil`. Otherwise, returns `f(self!)`. func map<U>(f: (T) -> U) -> U? ! /// Returns a mirror that reflects `self`. func getMirror() -> MirrorType ! /// Create an instance initialized with `nil`. init(nilLiteral: ()) }
  • 36. Optional<T> ? gGeneric Enum ? gϤäǡ؄eQܤƤ ? cf. http://qiita.com/koher/items/ 5dd6ce7427e7ecff4249 ? Failable<T>ͬ褦ˣǤ
  • 37. Optional as ? T⤷ʤǤϤʤT䡹 ? ˴뤿ˤ_Ҫ ? binding/coalescing/unwrapping ? _˲뷽⤢ ? mapping/chaining
  • 38. Optional Binding var optionalInt: Int? ! if let int = optionalInt { // int: Int println("optionalInt was (int)") } else { println("optionalInt was nil") } ! var array = [1, 2, 3, 4] while let item = array.last { // item: Int println("(item)") array.removeLast() }
  • 39. _: Optional Binding ? trueuĤ `bindƤ ? һȤһbindǤʤΤ϶ٲ
  • 40. Optional Coalescing optionalInt ?? 3 ! // ȵȁ optionalInt != nil ? optionalInt! : 3 ! // 뤤ϣ func coalesce<T>(lhs: T?, rhs: @autoclosure () -> T) -> T { if let lhs = lhs { return lhs } else { return rhs() } } coalesce(optionalInt, 3)
  • 41. _: Optional Coalescing ? _줿_ ? _ʤä_ʤ ? ˥ǥեȂ򷵤
  • 42. oʸ_: Forced Unwrapping optionalInt! ? Ф줬뤬ʤ ? ԤΤʹ٤ǤϤʤ ? ȫ^Ǥʤ阋ʤ
  • 43. 䤫M뷽 ? Optional mapping ? Optional chaining
  • 44. Optional Mapping /// v func triple(x: Int) -> Int { return x * 3 } ! optionalInt = 2 // ¤Ϥ٤.Some 6 optionalInt.map(triple) map(optionalInt, triple) optionalInt.map({ $0 * 3 })
  • 45. _ʤ: Optional Mapping ? ФeФ ? ФƤƄe䣨Optional ? nilʤnil򷵤
  • 46. Optional Mapping T U T -> U T? U? map(T?, T -> U) -> U?
  • 47. Optional Chaining class A { var b: B? } ! class B { var c: C? } ! class C { var i: Int = 1 } var a: A? = A() // a.b.c.i˥
  • 48. Optional Chaining var a: A? ! if let a = a { if let b = a.b { if let c = b.c { println("We finally find (c.i)!") } } }
  • 49. Optional Chaining var a: A? ! if let i = a?.b?.c?.i { println("Optional chaining makes (i)t easy.") }
  • 50. _ʤ: Optional Chaining ? ʧ뤫⤷ʤӳBiǤ ? ʧФȤˤMޤnil
  • 52. Optional Chaining a.b A? A?ͤbȤФϤʤ
  • 54. Optional Chaining a?.b?.c?.i A() or nil anilSomeΤɤ餫
  • 55. Optional Chaining a?.b?.c?.i A() B? or nil Someʤb˴
  • 56. Optional Chaining a?.b?.c?.i A() B? or nil nil nilʤ餽ǽK
  • 57. Optional Chaining a?.b?.c?.i A() B? or nil nil bB?ͤΉ
  • 58. Optional Chaining a?.b?.c?.i A() B() C? or or nil nil nil ͬ褦˷
  • 59. Optional Chaining a?.b?.c?.i A() B() C() 7 or or or nil nil nil nil ͬ
  • 60. ֱƤߤ extension Optional { func chain<U>(f: T -> U?) -> U? { if let s = self { return f(s) } else { return nil } } } ! if let i = a.chain({ $0.b }).chain({ $0.c }).chain({ $0.i }) { println("(i)") } ! // _ˤϡhʡԣYϵȤʤ룩 // let k = a.chain({ $0.b.chain({ $0.c.chain({ $0.i }) }) })
  • 61. ʤֱΣ ? vˤʹ褦ˤ ? 줬դۤǤ
  • 62. Failable Halve Int Int? // Ǹ줿뤱ɸʤä餢루ݤΤʤv func failableHalve(x: Int) -> Int? { if x % 2 == 0 { return x / 2 } else { return nil } } ! if let a = failableHalve(x) { println("Halve((x)) = (a)") } else { println("Failed") }
  • 63. Failable Halve Again Int Int? if let a = failableHalve(x) { if let b = failableHalve(a) { println("Halve^2((x)) = (b)") } else { println("Failed") } } else { println("Failed") } Int Int?
  • 64. Failable Halve The 3rd Int Int? if let a = failableHalve(x) { if let b = failableHalve(a) { if let c = failableHalve(b) { println("Halve^3((x)) = (c)") } else { println("Failed") } } else { println("Failed") } } else { println("Failed") } Int Int? Int Int?
  • 65. Failable Halve Chaining Int Int? if let a = failableHalve(x).chain(failableHalve).chain(failableHalve) { println("Halve^3((x)) = (a)") } else { println("Failed") } Int? Int?
  • 66. Failable Halve Chaining Int Int? Int? Int? 24 failableHalve(24) // Some 12 failableHalve(24).chain(failableHalve) // Some 6 failableHalve(24).chain(failableHalve).chain(failableHalve) // Some 3 failableHalve(24).chain(failableHalve).chain(failableHalve).chain(failableHalve) // nil ! 36 failableHalve(36) // Some 18 failableHalve(36).chain(failableHalve) // Some 9 failableHalve(36).chain(failableHalve).chain(failableHalve) // nil failableHalve(36).chain(failableHalve).chain(failableHalve).chain(failableHalve) // nil
  • 68. Optional Chaining T f U? f(t): U?
  • 69. Optional Chaining U g V? T f U? f(t): U?
  • 70. Optional Chaining g f V? T U? f(t).chain(g): V?
  • 71. Optional Chaining g V h W? f V? T U? f(t).chain(g): V?
  • 72. Optional Chaining g h W? f V? T U? f(t).chain(g).chain(h): W?
  • 74. Array Mapping T [T] T -> U U [U] map([T], T -> U) -> [U]
  • 75. Optional Mapping T U T -> U T? U? map( T?, T -> U) -> U?
  • 77. Optional as ״r ? ȤǡOptionalϡnil⤷ʤ ״rcontextFƤ ? ArrayϤɤ״rFƤ룿 ? _Ƥʤ
  • 78. Array as ״r Kyoto
  • 79. ĿȾˤ (0, 0) Kyoto
  • 80. i (0, 1) (-1,0) (1, 0) (0,-1) Kyoto
  • 81. i /// typealias Position = (Int, Int) ! /// |ϱΤɤؚiޤ func walk(from: Position) -> [Position] { let (x, y) = from return [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)] } ! walk((0, 0)) // [(-1, 0), (1, 0), (0, -1), (0, 1)]
  • 84. Array Chaining T [U] U [V] V [W]
  • 85. Array Chaining extension Array { func chain<U>(f: Element -> [U]) -> [U] { var ys = [U]() for x in self { ys += f(x) } return ys } } ! walk((0, 0)).chain(walk).chain(walk)
  • 88. BFTask doHeavyJobAsync1().continueWithBlock { (task: BFTask!) -> BFTask in let result = task.result as NSString self.resultLabel1.text = result self.resultLabel2.text = "I..." return self.doHeavyJobAsync2(result) }.continueWithBlock { (task: BFTask!) -> BFTask in let result = task.result as NSString self.resultLabel2.text = result self.resultLabel3.text = "I..." return self.doHeavyJobAsync3(result) }.continueWithBlock { (task: BFTask!) -> AnyObject! in let result = task.result as NSString self.resultLabel3.text = result return nil }
  • 89. BFTask private func doHeavyJobAsync2(prevResult: String) -> BFTask { var completionSource = BFTaskCompletionSource() // 5΄I // gõĤˤϡAFNetworkingcompletion֥åȤsetResult륤` Util.delay(5, { completionSource.setResult(prevResult + "???") }) return completionSource.task }
  • 90. Task<T> class Task<T: AnyObject> { private let task: BFTask ! init(task: BFTask) { self.task = task } var result: T? { return task.result as? T } func chain<U: AnyObject>(f: (T -> Task<U>)) -> Task<U> { let newTask = task.continueWithBlock { f($0.result as T).task } return Task<U>(task: newTask) } }
  • 91. Task򷵤v private func doHeavyJobAsync2(prevResult: NSString) -> Task<NSString> { let source = Source<NSString>() // 5΄I // gõĤˤϡAFNetworkingcompletion֥åȤsetResult륤` delay(5, { source.setResult(prevResult + "???" as NSString) }) return source.task }
  • 92. Task Chaining T U U V V W ͬ ͬ ͬ
  • 93. Task Chaining func heavyTask1(Void) -> Task<NSString> { return delayedTask(5) { NSLog("First Task (no params)") return "123" as NSString } } ! func heavyTask2(string: NSString) -> Task<NSNumber> { return delayedTask(5) { NSLog("Second Task (param: (string))") return NSNumber(integer: (string as String).toInt() ?? 0) } } ! func heavyTask3(number: NSNumber) -> Task<NSNumber> { return delayedTask(5) { NSLog("Third Task (param: (number))") return NSNumber(integer: number.integerValue * 2) } }
  • 94. Task Chaining NSLog("Start") heavyTask1().chain(heavyTask2).chain(heavyTask3) NSLog("End") 2014-11-27 21:15:24.659 MySweetSwift[18362:314049] Start 2014-11-27 21:15:24.663 MySweetSwift[18362:314049] End 2014-11-27 21:15:29.663 MySweetSwift[18362:314049] First Task (no params) 2014-11-27 21:15:35.136 MySweetSwift[18362:314049] Second Task (param: 123) 2014-11-27 21:15:40.636 MySweetSwift[18362:314049] Third Task (param: 123)
  • 95. ޤȤ ? OptionalϤ襤 ? ArrayOptionalƤƤ ? ʤǤꡢ״rǤ ? ͬڄIͬ褦Ҋ뤳ȤǤ ? Optional ChainingΤ褦ʕǤơ BFTaskƤƤ
  • 96. ο
  • 97.