+ All Categories
Home > Engineering > Idioms in swift 2016 05c

Idioms in swift 2016 05c

Date post: 12-Apr-2017
Category:
Upload: kaz-yoshikawa
View: 135 times
Download: 2 times
Share this document with a friend
51
Idioms in Swift Kaz Yoshikawa May 2016
Transcript
Page 1: Idioms in swift 2016 05c

Idioms in SwiftKaz Yoshikawa

May 2016

Page 2: Idioms in swift 2016 05c

About me

Page 3: Idioms in swift 2016 05c

Kaz Yoshikawa• Electricwoods LLC 代表 / Digital Lynx Systems Inc. 副代表

• e-mail: [email protected]

• LinkedIn: https://www.linkedin.com/in/kazyoshikawa

• Working History

• Adobe Systems (Tokyo)

• Lionbridge (Tokyo)

• Quark (Tokyo / Denver)

• Hummingbird Communications (Mt. View, USA)

• Fact International (Vancouver, Canada)

• Perle Systems (Toronto, Canada), etc.

Page 4: Idioms in swift 2016 05c

Engineering

Page 5: Idioms in swift 2016 05c

将棋盤Kit

Page 6: Idioms in swift 2016 05c

What is Idiom?

Page 7: Idioms in swift 2016 05c

Optional

Page 8: Idioms in swift 2016 05c

guard let• 二つの引数が nil でない事を保証する

func add(a: Int?, _ b: Int?) -> Int? {

guard let a = a, let b = b else { return nil }

return a + b }

Page 9: Idioms in swift 2016 05c

if let• if let を使う

func add(a: Int?, _ b: Int?) -> Int? {

if let a = a, let b = b { return a + b } return nil

}

Page 10: Idioms in swift 2016 05c

where• guard let で0以上を保証する

func add(a: Int?, _ b: Int?) -> Int? { guard let a = a, let b = b where a >= 0 && b >= 0 else { return nil } return a + b }

• if let でも0以上を保証する func add(a: Int?, _ b: Int?) -> Int? { if let a = a, let b = b where a >= 0 && b >= 0 { return a + b } return nil }

Page 11: Idioms in swift 2016 05c

nil-coalescing Operator• nil の場合は 0 として扱う func add(a: Int?, b: Int?) -> Int {

return (a ?? 0) + (b ?? 0)

}

Page 12: Idioms in swift 2016 05c

Switch

Page 13: Idioms in swift 2016 05c

Optional in Switch• 実は optional も switch 文に使える

func countryName(identifier: String?) -> String? { switch identifier { case "JP"?: return "Japan" case "GB"?: return "England" case "US"?: return "U.S.A." default: return nil } }

Page 14: Idioms in swift 2016 05c

Late InitializingImmutable Variables

• 初期値を後で設定する不定変数

let color: UIColor // "= value"

switch value % 3 { case 0: color = UIColor.whiteColor() case 1: color = UIColor.redColor() default: fatalError() }

• 初期化しないケースがあると、コンパイルエラー

Page 15: Idioms in swift 2016 05c

Complex switch casesfor thing in things { switch thing { case 0 as Int: print("zero as an Int") case 0 as Double: print("zero as a Double") case let someInt as Int: print("an integer value of \(someInt)") case let someDouble as Double where someDouble > 0: print("a positive double value of \(someDouble)") case is Double: print("some other double value") case let someString as String: print("a string value of \"\(someString)\"") case let (x, y) as (Double, Double): print("an (x, y) point at \(x), \(y)") case let movie as Movie: print("Movie:'\(movie.name)'") default: print("something else") } }

Page 16: Idioms in swift 2016 05c

Implicitly Unwrapped Optional

Page 17: Idioms in swift 2016 05c

Implicitly Unwrapped Optional with if statement

• Implicitly Unwrapped Optional でも if let は 使える

let a: Int! if let a = a { print("\(a)") }

Page 18: Idioms in swift 2016 05c

Implicitly Unwrapped Optional with guard statement

• Implicitly Unwrapped Optional でも guard は 使える

class MyObject { var value: Int! = nil func some() { guard let value = value else { return } print("\(value)") } func other() { guard value != nil else { return } print("\(value)") } }

Page 19: Idioms in swift 2016 05c

Associated Values

Page 20: Idioms in swift 2016 05c

Defining Associated Value

enum Element { case String(Swift.String) case Boolean(Bool) case Integer(Int) case Float(Swift.Float) case Dictionary([Swift.String: Element]) case Array([Element]) case Null }

let integer = Element.Integer(42) let city = Element.String("Tokyo") let cities = Element.Array([city]) let dictionary = Element.Dictionary(["items": array])

Page 21: Idioms in swift 2016 05c

Extracting Associated Values Using switch Statement

• Associated Value を Switch文で取り出す

switch element { case .String(let string): print("string: \(string)") case .Boolean(let value): print("boolean: \(value)") case .Integer(let value): print("ineteger: \(value)") case .Float(let value): print("float: \(value)") case .Dictionary(let dictionary): print("dictionary: \(dictionary)") case .Array(let array): print("array: \(array)") case .Null: print("null") }

Page 22: Idioms in swift 2016 05c

Extracting Associated Values using if Statement

• If 文でも取り出せます

let element1: Element = … if case .String(let string) = element1 { print("\(string)") }

• Optional な場合でも取り出せます

let element: Element? = … if case .String(let string)? = element1 { print("\(string)") }

Page 23: Idioms in swift 2016 05c

Extracting Associated Values

• division -> members -> person -> name

let name = Element.String("John") let john = Element.Dictionary(["name": name]) let members = Element.Array([john]) let group = Element.Dictionary(["members": members])

• 一発で取り出せる

if case .Dictionary(let group) = group, case .Array(let members)? = division["members"], case .Dictionary(let member)? = members.first, case .String(let name)? = member["name"] { print("\(name)") // John }

Page 24: Idioms in swift 2016 05c

Closure

Page 25: Idioms in swift 2016 05c

Basic Closureclass MyViewController: UIViewController { var state: Bool = false func toggle(animated: Bool) { let closure = { self.view.backgroundColor = self.state ? UIColor.redColor() : UIColor.whiteColor() self.state = !self.state } if animated { UIView.animateWithDuration(0.3) { closure() // <-- Here!! } } else { closure() // <-- Here!! } } }

Page 26: Idioms in swift 2016 05c

Basic Closureclass MyViewController: UIViewController { var state: Bool = false func toggle(animated: Bool) { let closure = { self.view.backgroundColor = self.state ? UIColor.redColor() : UIColor.whiteColor() self.state = !self.state } if animated { UIView.animateWithDuration(0.3) { closure() // <-- Here!! } } else { closure() // <-- Here!! } } }

Page 27: Idioms in swift 2016 05c

Execute on Main Thread func dispatch_sync_main(block: () -> Void) { if NSThread.isMainThread() { block() } else { dispatch_sync(dispatch_get_main_queue()) { () -> Void in block() } } }

dispatch_sync_main { self.tableView.reloadData() }

Page 28: Idioms in swift 2016 05c

Execute on Main Thread func dispatch_sync_main(block: () -> Void) { if NSThread.isMainThread() { block() } else { dispatch_sync(dispatch_get_main_queue()) { () -> Void in block() } } }

dispatch_sync_main { self.tableView.reloadData() }

Page 29: Idioms in swift 2016 05c

Execute on Main Thread func dispatch_sync_main(block: () -> Void) { if NSThread.isMainThread() { block() } else { dispatch_sync(dispatch_get_main_queue()) { () -> Void in block() } } }

dispatch_sync_main { self.tableView.reloadData() }

Page 30: Idioms in swift 2016 05c

Initialize Immutable Variable Using Closure

• closure と switch 文を使うとかっこよく書ける let color: UIColor = { switch value % 2 { case 0: return UIColor.whiteColor() case 1: return UIColor.redColor() default: fatalError() } }() // "()" !!

Page 31: Idioms in swift 2016 05c

Initialize Immutable Variable Using Closure

• closure と switch 文を使うとかっこよく書ける let color: UIColor = { switch value % 2 { case 0: return UIColor.whiteColor() case 1: return UIColor.redColor() default: fatalError() } }() // "()" !!

Page 32: Idioms in swift 2016 05c

Changing Behavior with Using Closure

typealias DrawingHandler = (UIPanGestureRecognizer)->()

class MyView: UIView { func panGesture(sender: UIPanGestureRecognizer) { self.drawingHandler(sender) } var drawingHandler: DrawingHandler! let ovalGesture: DrawingHandler = { gesture in // draw oval } let rectangleGesture: DrawingHandler = { gesture in // draw rectangle } }

Page 33: Idioms in swift 2016 05c

Changing Behavior with Using Closure

typealias DrawingHandler = (UIPanGestureRecognizer)->()

class MyView: UIView { func panGesture(sender: UIPanGestureRecognizer) { self.drawingHandler(sender) } var drawingHandler: DrawingHandler! let ovalGesture: DrawingHandler = { gesture in // draw oval } let rectangleGesture: DrawingHandler = { gesture in // draw rectangle } }

Page 34: Idioms in swift 2016 05c

lazy

Page 35: Idioms in swift 2016 05c

When should I use lazy?• 処理が重くて初期化時に実行するのは不都合

• 大人の理由で init で初期化できないプロパティ

Page 36: Idioms in swift 2016 05c

Using lazy varclass MyObject {

lazy var path: String = { return NSBundle.mainBundle() .pathForResource("text", ofType: "txt")! }()

lazy var text: String = { return try! String(contentsOfFile: self.path) }() }

Page 37: Idioms in swift 2016 05c

Initializing code per instance

• 何回呼ばれてもインスタンス毎に一度のみ初期化するコード

class MyView: UIView {

override func layoutSubviews() { print("MyView: \(#function)") super.layoutSubviews() setup() }

private lazy var setup: (()->()) = { print("MyView: \(#function)") // さまざまな初期化のコード return {} }() }

http://qiita.com/codelynx/items/f0243d631f2448e89026

Page 38: Idioms in swift 2016 05c

Singleton

Page 39: Idioms in swift 2016 05c

Singleton• 典型的なシングルトン class Manager { static let sharedManager = Manager() private init() { } }

• クロージャーを使ったシングルトン

class Manager { static var sharedManager: Manager = { return Manager() }() private init() { } }

http://qiita.com/codelynx/items/a936afe0a45d4cf5abfb

Page 40: Idioms in swift 2016 05c

Updating C style `for` statement

http://qiita.com/codelynx/items/899c26dd2cbdba7d2b00

Page 41: Idioms in swift 2016 05c

for var i = 0 ; i < 100 ; i++// C-Style for statement for var i = 0 ; i < 100 ; i++ { print("\(i)") }

// Swift 3.0 ready (0 ..< 100).forEach { print("\($0)") }

// Swift 3.0 ready for i in (0 ..< 100) { print("\(i)") }

Page 42: Idioms in swift 2016 05c

for var i = 99 ; i >= 0 ; i--// C-Style for statement for var i = 99 ; i >= 0 ; i-- { print("\(i)") }

// Swift 3.0 ready (0 ..< 100).reverse().forEach { print("\($0)") }

// Swift 3.0 ready for i in (0 ..< 100).reverse() { print("\(i)") }

Page 43: Idioms in swift 2016 05c

for var i = 0; i < 100 ; i += 2// C-Style for statement for var i = 0; i < 100 ; i += 2 { print("\(i)") }

// Swift 3.0 ready 0.stride(to: 100, by: 2).forEach { print("\($0)") }

Page 44: Idioms in swift 2016 05c

for var i = 98 ; i >= 0 ; i -= 2

// C-Style for statement for var i = 98 ; i >= 0 ; i -= 2 { print("\(i)") }

// Swift 3.0 ready 98.stride(through: 0, by: -2).forEach { print("\($0)") }

// Swift 3.0 ready

0.stride(to: 100, by: 2).reverse().forEach { print("\($0)") }

// Swift 3.0 ready for i in 0.stride(to: 100, by: 2).reverse() { print("\(i)") }

Page 45: Idioms in swift 2016 05c

for without increment• 次の再初期化式の指定がなく、刻みが不定の場合 // C-Style for statement for var i = 0 ; i < 100 ; { print("\(i)") if (i * i) % 2 == 0 { i += 1 } else { i += 2 } }

// Swift 3.0 ready var i = 0 while i < 100 { print("\(i)") if (i * i) % 2 == 0 { i += 1 } else { i += 2 } }

Page 46: Idioms in swift 2016 05c

Computed Properties and Property Observer

Page 47: Idioms in swift 2016 05c

Custom Propertyclass MyObject {

private var _name: String = ""

var name: String { get { return _name } set { _name = newValue } }

}

Page 48: Idioms in swift 2016 05c

Property Observerclass MyView: UIView {

var name: String = "" { didSet { self.setNeedsLayout() } }

}

Page 49: Idioms in swift 2016 05c

Wrap Up

Page 50: Idioms in swift 2016 05c

Wrap up• 知っていても、0.2秒で思い出せない記法はいろいろある

• Open Source を散策して先人達の記法を参考に

• 気がついた記法があれば、playground などにメモ

• 時々、swift 文法書を眺め直してみよう

Page 51: Idioms in swift 2016 05c

Thank YouKaz Yoshikawa

[email protected]


Recommended