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

Swift4.2で追加されたDynamic Member Lookupを使ってみよう

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for tamappe tamappe
March 19, 2019

Swift4.2で追加されたDynamic Member Lookupを使ってみよう

try! Swift Pre Talks でお話ししました登壇資料です @tamappe

Avatar for tamappe

tamappe

March 19, 2019
Tweet

More Decks by tamappe

Other Decks in Technology

Transcript

  1. struct Me { let name = “Yosuke Tamaoki” let age

    = 31 let company = “Summer" + “Freelance“ let os = "iOS" + "Android" let hobby = "Splatoon2" + “Poker" struct Language { let swift let objective-c let java let kotlin } } "CPVU!UBNBQQF
  2. // Dictionary let classRoom: [String: Any] = [ "teacher": "Yamada",

    “studentNum”: 30 ] // before let teacher = classRoom["teacher"] // "Yamada" let count = classRoom["studentNum"] // 30 let teacher = classRoom.teacher // compile error let count = classRoom.studentNum // compile error // after let teacher = classRoom.teacher // "Yamada" let count = classRoom.studentNum // 30 1PXFSPGEZOBNJDNFNCFSMPPLVQ
  3. $MBTTDBTF @dynamicMemberLookup class User { let firstName: String let lastName:

    String let age: Int init(firstName: String, lastName: String, age: Int) { self.firstName = firstName self.lastName = lastName self.age = age } subscript(dynamicMember key: String) -> Any { switch key { case "upperFirstName": return firstName.uppercased() case "upperLastName": return lastName.uppercased() case "adalt": return 30 case "children": return 15 default: return "" } } }
  4. $MBTTDBTF @dynamicMemberLookup class User { let firstName: String let lastName:

    String let age: Int init(firstName: String, lastName: String, age: Int) { self.firstName = firstName self.lastName = lastName self.age = age } subscript(dynamicMember key: String) -> Any { switch key { case "upperFirstName": return firstName.uppercased() case "upperLastName": return lastName.uppercased() case "adalt": return 30 case "children": return 15 default: return "" } } }
  5. 6TFDBTF let hanakoYamada = User(firstName: "Hanako", lastName: "Yamada", age: 20)

    print(hanakoYamada.firstName) // "Hanako" print(hanakoYamada.lastName) // "Yamada" print(hanakoYamada.age) // 20 print(hanakoYamada.upperFirstName) // "HANAKO" print(hanakoYamada.upperLastName) // "YAMADA" print(hanakoYamada.adalt) // 30 print(hanakoYamada.children) // 15 print(hanakoYamada.young) // ""
  6. 1SPUPDPMDBTF @dynamicMemberLookup protocol SampleProtocol { associatedtype Key associatedtype Value subscript(key:

    Key) -> Value? { get } } extension SampleProtocol where Key == String { subscript(dynamicMember member: String) -> Value? { return self[member] } } extension Dictionary: SampleProtocol {} 1SPUPDPMFYUFOTJPO
  7. 6TFDBTF let hanakoDic: [String : Any] = [ "firstName": "hanako",

    "lastName": "yamada", "age": 20 ] print(hanakoDic.firstName as! String) // “hanako" print(hanakoDic.age as! Int) // 20
  8. &OVNDBTF @dynamicMemberLookup enum JSON { case number(Int) case string(String) case

    array([JSON]) case dictionary([String: JSON]) subscript(dynamicMember key: String) -> JSON? { guard case .dictionary(let dict) = self else { return nil } return dict[key] } } extension JSON { var numberValue: Int? { guard case .number(let n) = self else { return nil } return n } var stringValue: String? { guard case .string(let s) = self else { return nil } return s } subscript(index: Int) -> JSON? { guard case .array(let arr) = self, arr.indices.contains(index) else { return nil } return arr[index] } subscript(key: String) -> JSON? { guard case .dictionary(let dict) = self else { return nil } return dict[key] } } +40/
  9. &OVNDBTF @dynamicMemberLookup enum JSON { case number(Int) case string(String) case

    array([JSON]) case dictionary([String: JSON]) subscript(dynamicMember key: String) -> JSON? { guard case .dictionary(let dict) = self else { return nil } return dict[key] } } +40/
  10. &OVNDBTF extension JSON { var numberValue: Int? { guard case

    .number(let n) = self else { return nil } return n } var stringValue: String? { guard case .string(let s) = self else { return nil } return s } subscript(index: Int) -> JSON? { guard case .array(let arr) = self, arr.indices.contains(index) else { return nil } return arr[index] } subscript(key: String) -> JSON? { guard case .dictionary(let dict) = self else { return nil } return dict[key] } } +40/
  11. 6TFDBTF let json = JSON.dictionary([ "firstName": .string("hanako"), "lastName": .string("Yamada"), "age":

    .number(20), "language": .array([ .string(“Swift"), .string("Objective-c"), .string("Kotlin"), .string("Java"), ]) ]) if let firstName = json.firstName?.stringValue { print(firstName) // "hanako" }