Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Idioms in Swift

Idioms in Swift

Easy to forget common Swift idioms

codelynx

May 30, 2016
Tweet

More Decks by codelynx

Other Decks in Programming

Transcript

  1. ,B[:PTIJLBXB w &MFDUSJDXPPET--$୅ද%JHJUBM-ZOY4ZTUFNT*OD෭୅ද w FNBJMLB[!EJHJUBMMZOYDPN w -JOLFE*OIUUQTXXXMJOLFEJODPNJOLB[ZPTIJLBXB w 8PSLJOH)JTUPSZ w

    "EPCF4ZTUFNT 5PLZP  w -JPOCSJEHF 5PLZP  w 2VBSL 5PLZP%FOWFS  w )VNNJOHCJSE$PNNVOJDBUJPOT .U7JFX 64"  w 'BDU*OUFSOBUJPOBM 7BODPVWFS $BOBEB  w 1FSMF4ZTUFNT 5PSPOUP $BOBEB FUD
  2. HVBSEMFU w ೋͭͷҾ਺͕OJMͰͳ͍ࣄΛอূ͢Δ func add(a: Int?, _ b: Int?) ->

    Int? { guard let a = a, let b = b else { return nil } return a + b }
  3. JGMFU w JGMFUΛ࢖͏ func add(a: Int?, _ b: Int?) ->

    Int? { if let a = a, let b = b { return a + b } return nil }
  4. XIFSF w HVBSEMFUͰ̌Ҏ্Λอূ͢Δ 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 } w JGMFUͰ΋̌Ҏ্Λอূ͢Δ func add(a: Int?, _ b: Int?) -> Int? { if let a = a, let b = b where a >= 0 && b >= 0 { return a + b } return nil }
  5. 0QUJPOBMJO4XJUDI w ࣮͸PQUJPOBM΋TXJUDIจʹ࢖͑Δ func countryName(identifier: String?) -> String? { switch

    identifier { case "JP"?: return "Japan" case "GB"?: return "England" case "US"?: return "U.S.A." default: return nil } }
  6. -BUF*OJUJBMJ[JOH
 *NNVUBCMF7BSJBCMFT w ॳظ஋ΛޙͰઃఆ͢Δෆఆม਺ let color: UIColor // "= value"

    switch value % 3 { case 0: color = UIColor.whiteColor() case 1: color = UIColor.redColor() default: fatalError() } w ॳظԽ͠ͳ͍έʔε͕͋ΔͱɺίϯύΠϧΤϥʔ
  7. $PNQMFYTXJUDIDBTFT for 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") } }
  8. *NQMJDJUMZ6OXSBQQFE0QUJPOBM XJUIHVBSETUBUFNFOU w *NQMJDJUMZ6OXSBQQFE0QUJPOBMͰ΋HVBSE͸࢖͑Δ 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)") } }
  9. %FpOJOH"TTPDJBUFE 7BMVF 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])
  10. &YUSBDUJOH"TTPDJBUFE7BMVFT 6TJOHTXJUDI4UBUFNFOU w "TTPDJBUFE7BMVFΛ4XJUDIจͰऔΓग़͢ 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") }
  11. &YUSBDUJOH"TTPDJBUFE 7BMVFTVTJOHJG4UBUFNFOU w *GจͰ΋औΓग़ͤ·͢ let element1: Element = … if

    case .String(let string) = element1 { print("\(string)") } w 0QUJPOBMͳ৔߹Ͱ΋औΓग़ͤ·͢ let element: Element? = … if case .String(let string)? = element1 { print("\(string)") }
  12. &YUSBDUJOH"TTPDJBUFE 7BMVFT w EJWJTJPONFNCFSTQFSTPOOBNF let name = Element.String("John") let john

    = Element.Dictionary(["name": name]) let members = Element.Array([john]) let group = Element.Dictionary(["members": members]) w ҰൃͰऔΓग़ͤΔ 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 }
  13. #BTJD$MPTVSF class 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!! } } }
  14. #BTJD$MPTVSF class 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!! } } }
  15. &YFDVUFPO.BJO5ISFBE 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() }
  16. &YFDVUFPO.BJO5ISFBE 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() }
  17. &YFDVUFPO.BJO5ISFBE 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() }
  18. *OJUJBMJ[F*NNVUBCMF 7BSJBCMF6TJOH$MPTVSF w DMPTVSFͱTXJUDIจΛ࢖͏ͱ͔ͬ͜Α͘ॻ͚Δ 
 let color: UIColor = {

    switch value % 2 { case 0: return UIColor.whiteColor() case 1: return UIColor.redColor() default: fatalError() } }() // "()" !!
  19. *OJUJBMJ[F*NNVUBCMF 7BSJBCMF6TJOH$MPTVSF w DMPTVSFͱTXJUDIจΛ࢖͏ͱ͔ͬ͜Α͘ॻ͚Δ 
 let color: UIColor = {

    switch value % 2 { case 0: return UIColor.whiteColor() case 1: return UIColor.redColor() default: fatalError() } }() // "()" !!
  20. $IBOHJOH#FIBWJPSXJUI 6TJOH$MPTVSF 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 } }
  21. $IBOHJOH#FIBWJPSXJUI 6TJOH$MPTVSF 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 } }
  22. 6TJOHMB[ZWBS class MyObject { lazy var path: String = {

    return NSBundle.mainBundle() .pathForResource("text", ofType: "txt")! }() lazy var text: String = { return try! String(contentsOfFile: self.path) }() }
  23. *OJUJBMJ[JOHDPEFQFS JOTUBODF w Կճݺ͹Εͯ΋ΠϯελϯεຖʹҰ౓ͷΈॳظԽ͢Δίʔυ class MyView: UIView { override func

    layoutSubviews() { print("MyView: \(#function)") super.layoutSubviews() setup() } private lazy var setup: (()->()) = { print("MyView: \(#function)") // ͞·͟·ͳॳظԽͷίʔυ return {} }() } IUUQRJJUBDPNDPEFMZOYJUFNTGEGF
  24. 4JOHMFUPO w యܕతͳγϯάϧτϯ 
 class Manager { static let sharedManager

    = Manager() private init() { } } w ΫϩʔδϟʔΛ࢖ͬͨγϯάϧτϯ class Manager { static var sharedManager: Manager = { return Manager() }() private init() { } } http://qiita.com/codelynx/items/a936afe0a45d4cf5abfb
  25. GPSWBSJJJ // 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)") }
  26. GPSWBSJJJ // 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)") }
  27. GPSWBSJJJ  // 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)") }
  28. GPSWBSJJJ  // 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)") }
  29. GPSXJUIPVUJODSFNFOU w ࣍ͷ࠶ॳظԽࣜͷࢦఆ͕ͳ͘ɺࠁΈ͕ෆఆͷ৔߹ // 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 } }
  30. $VTUPN1SPQFSUZ class MyObject { private var _name: String = ""

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