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

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

tamappe
March 19, 2019

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

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

tamappe

March 19, 2019
Tweet

More Decks by tamappe

Other Decks in Technology

Transcript

  1. -FU`TVTF
    %ZOBNJD.FNCFS-PPLVQ
    JOUSPEVDFEJO4XJGU
    !UBNBQQF
    USZ4XJGU1SF5BMLT

    View Slide

  2. 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

    View Slide

  3. 1PXFSPGEZOBNJDNFNCFSMPPLVQ
    )PXUP*NQMFNFOU
    4BNQMFDPEFT
    $PODMVTJPO
    4VNNBSZPGNZUBML
    !EZOBNJD.FNCFS-PPLVQ
    QSPUPDPM\^

    View Slide

  4. // 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

    View Slide

  5. "EE!EZOBNJD.FNCFS-PPLVQ
    CFGPSFUIFDMBTT
    "EElTVCTDSJQUzEFpOJUJPO
    "EEMBCFMEZOBNJD.FNCFSUP
    UIFBSHVNFOUPGTVCTDSJQUEFpOJUJPO
    )PXUP*NQMFNFOU

    View Slide

  6. 4BNQMFDPEF
    $MBTT
    4USVDU
    1SPUPDPM
    &OVN
    &YQMBJO
    &YQMBJO
    TMJEFPOMZ
    TMJEFPOMZ

    View Slide

  7. $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 ""
    }
    }
    }

    View Slide

  8. $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 ""
    }
    }
    }

    View Slide

  9. 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) // ""

    View Slide

  10. TUSVDUDBTF
    @dynamicMemberLookup
    struct Person {
    subscript(dynamicMember name: String) -> String {
    return "Hello, \(name)"
    }
    }

    View Slide

  11. TUSVDUDBTF
    @dynamicMemberLookup
    struct Person {
    subscript(dynamicMember name: String) -> String {
    return "Hello, \(name)"
    }
    }

    View Slide

  12. 6TFDBTF
    let person = Person()
    print(person.swift) // "Hello, swift”
    print(person.hanako) // "Hello, hanako”
    print(person.taro) // "Hello, taro"

    View Slide

  13. 5IBU`T"MM
    5IBOLZPV
    https://blog.tamappe.com

    View Slide

  14. 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

    View Slide

  15. 6TFDBTF
    let hanakoDic: [String : Any] = [
    "firstName": "hanako",
    "lastName": "yamada",
    "age": 20
    ]
    print(hanakoDic.firstName as! String) // “hanako"
    print(hanakoDic.age as! Int) // 20

    View Slide

  16. &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/

    View Slide

  17. &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/

    View Slide

  18. &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/

    View Slide

  19. 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"
    }

    View Slide