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

今更聞けない?Struct と class の使い分け方

Avatar for Elvis Shi Elvis Shi
February 08, 2017

今更聞けない?Struct と class の使い分け方

Avatar for Elvis Shi

Elvis Shi

February 08, 2017
Tweet

More Decks by Elvis Shi

Other Decks in Programming

Transcript

  1. Who am I? MAGES. Inc. Game Div. (5pb.Games) iOS Developer

    @loveeʢ੕໺ܙྤʣ ͷΞγελϯτP←!!!!
  2. struct class ܕ ஋ܕ ࢀরܕ ܧঝ ෆՄ Մೳ deinit ͳ͠

    ͋Γ ๏ ੜ੒ίετ௿͍ ๏ ॥؀ࢀর໰୊͕ͳ͍ ๏ εϨουηʔϑ ๏ ॲཧ͕୯७Ͱ෼͔Γ΍͍͢ ๏ etc…
  3. struct Player { let name: String // ໊લɺมߋෆՄ var level

    = 1 // ͦͷଞॾʑ init(name: String) { self.name = name } mutating func levelUp() { level += 1 } } var player = Player(name: "ྋ෩੨༿") { didSet { // ηʔϒσʔλ } } player.levelUp() // didSet ͕ݺ͹ΕͯϢʔβσʔλ͕ηʔϒ͞ΕΔ
  4. struct Player { let name: String // ໊લɺมߋෆՄ var level

    = 1 // ͦͷଞॾʑ init(name: String) { self.name = name } mutating func levelUp() { level += 1 } } var player = Player(name: "ྋ෩੨༿") { didSet { // ηʔϒσʔλ } } player.levelUp() // didSet ͕ݺ͹ΕͯϢʔβσʔλ͕ηʔϒ͞ΕΔ
  5. struct Player { let name: String // ໊લɺมߋෆՄ var level

    = 1 // ͦͷଞॾʑ init(name: String) { self.name = name } mutating func levelUp() { level += 1 } } var player = Player(name: "ྋ෩੨༿") { didSet { // ηʔϒσʔλ } } player.levelUp() // didSet ͕ݺ͹ΕͯϢʔβσʔλ͕ηʔϒ͞ΕΔ
 player = Player(name: "ࡩͶͶ") // ϩδοΫΤϥʔɿఆ਺Ͱ͋Δ player.name ͕มΘͬͯ͠·͏
  6. struct Player { let name: String // ໊લɺมߋෆՄ var level

    = 1 // ͦͷଞॾʑ init(name: String) { self.name = name } mutating func levelUp() { level += 1 } } var player = Player(name: "ྋ෩੨༿") { didSet { // ηʔϒσʔλ } } player.levelUp() // didSet ͕ݺ͹ΕͯϢʔβσʔλ͕ηʔϒ͞ΕΔ
 player = Player(name: "ࡩͶͶ") // ϩδοΫΤϥʔɿఆ਺Ͱ͋Δ player.name ͕มΘͬͯ͠·͏ 㨍㩆㏔⹻׳׻⹪⑉㌈ר挵㓱؃ש؆ק׿׻Ŏ
  7. switch instance { case is Data: useStruct() case is Object:

    useClass() case _: fatalError("ͪΌΜͱߟ͑Ζʂ") } 嗒嵿䥥鰛㏰❔鰘鰟 &CVC鰙1DLGEV鰑鰹
 鱣鱈鱻痓鰉鰴鰛鯵鰹
  8. protocol LoverBecomable { } struct Human { var name: String

    var item: String? var lover: LoverBecomable? init(name: String) { self.name = name } } extension Human: LoverBecomable { } var ktanaka = Human(name: "ాதݡ࣏") var maki = Human(name: "੢໦໺ਅඣ") ktanaka.lover = maki maki.item = "Bikini" (ktanaka.lover as? Human)?.item // nil ktanaka.lover === maki // Error: Binary operator '===' cannot be applied
  9. protocol LoverBecomable { } struct Human { var name: String

    var item: String? var lover: LoverBecomable? init(name: String) { self.name = name } } extension Human: LoverBecomable { } var ktanaka = Human(name: "ాதݡ࣏") var maki = Human(name: "੢໦໺ਅඣ") ktanaka.lover = maki maki.item = "Bikini" (ktanaka.lover as? Human)?.item // nil ktanaka.lover === maki // Error: Binary operator '===' cannot be applied ㌬↛؄؋
  10. protocol LoverBecomable { } struct Human { var name: String

    var item: String? var lover: LoverBecomable? init(name: String) { self.name = name } } extension Human: LoverBecomable { } var ktanaka = Human(name: "ాதݡ࣏") var maki = Human(name: "੢໦໺ਅඣ") ktanaka.lover = maki maki.item = "Bikini" (ktanaka.lover as? Human)?.item // nil ktanaka.lover === maki // Error: Binary operator '===' cannot be applied
  11. protocol LoverBecomable { } struct Human { var name: String

    var item: String? var lover: LoverBecomable? init(name: String) { self.name = name } } extension Human: LoverBecomable { } var ktanaka = Human(name: "ాதݡ࣏") var maki = Human(name: "੢໦໺ਅඣ") ktanaka.lover = maki maki.item = "Bikini" (ktanaka.lover as? Human)?.item // nil ktanaka.lover === maki // Error: Binary operator '===' cannot be applied
  12. protocol LoverBecomable: class { } class Human { var name:

    String var item: String? weak var lover: LoverBecomable? init(name: String) { self.name = name } } extension Human: LoverBecomable { } let ktanaka = Human(name: "ాதݡ࣏") let maki = Human(name: "੢໦໺ਅඣ") ktanaka.lover = maki maki.item = "Bikini" (ktanaka.lover as? Human)?.item // Bikini ktanaka.lover === maki // true
  13. class Human { // … var bankAccounts: [BankAccount] // …

    } protocol BankAccountDelegate: class { func account(_ account: BankAccount, changePasswordTo newPassword: String) throws -> Int func account(_ account: BankAccount, transfer amount: Int, to receiver: Int) throws } class BankAccount { let id: Int private(set) var hashedPassword: Int private(set) weak var delegate: BankAccountDelegate? // init(id: Int, encryptedPassword: Int, delegate: BankAccountDelegate) { … } func changePassword(to newPassword: String) { do { guard let delegate = self.delegate else { throw NSError() } let newHashedPassword = try delegate.account(self, changePasswordTo: newPassword) self.hashedPassword = newHashedPassword print("ύεϫʔυมߋ੒ޭ") } catch { print("ύεϫʔυมߋࣦഊ") } } func transfer(_ amount: Int, to receiver: Int) { do { guard let delegate = self.delegate else { throw NSError() } try delegate.account(self, transfer: amount, to: receiver) print("ૹۚ੒ޭ") } catch { print("ૹࣦۚഊ") } } }
  14. class Human { // … var bankAccounts: [BankAccount] // …

    } protocol BankAccountDelegate: class { func account(_ account: BankAccount, changePasswordTo newPassword: String) throws -> Int func account(_ account: BankAccount, transfer amount: Int, to receiver: Int) throws } class BankAccount { // … func changePassword(to newPassword: String) { // … } func transfer(_ amount: Int, to receiver: Int) { do { guard let delegate = self.delegate else { throw NSError() } try delegate.account(self, transfor: amount, to: receiver) print("ૹۚ੒ޭ") } catch { print("ૹࣦۚഊ") } } } let tanakaAccount = someBank.issueAccount(password: "1234") ktanaka.bankAccounts.append(tanakaAccount) let amazonAccountID = someBank.issueAccount(password: "J7BJuGy8ks2T").id ktanaka.bankAccounts[0].transfer(1000, to: amazonAccountID) // ૹۚ੒ޭ maki.bankAccounts.append(ktanaka.bankAccounts[0]) maki.bankAccounts[0].transfer(100_000, to: amazonAccountID) // ૹۚ੒ޭ ktanaka.bankAccounts[0].changePassword(to: “5678") maki.bankAccounts[0].transfer(500_000, to: amazonAccountID) // ૹۚ੒ޭʂʁ
  15. class Human { // … var bankAccounts: [BankAccount] // …

    } protocol BankAccountDelegate: class { func account(_ account: BankAccount, changePasswordTo newPassword: String) throws -> Int func account(_ account: BankAccount, transfer amount: Int, to receiver: Int) throws } class BankAccount { // … func changePassword(to newPassword: String) { // … } func transfer(_ amount: Int, to receiver: Int) { do { guard let delegate = self.delegate else { throw NSError() } try delegate.account(self, transfor: amount, to: receiver) print("ૹۚ੒ޭ") } catch { print("ૹࣦۚഊ") } } } let tanakaAccount = someBank.issueAccount(password: "1234") ktanaka.bankAccounts.append(tanakaAccount) let amazonAccountID = someBank.issueAccount(password: "J7BJuGy8ks2T").id ktanaka.bankAccounts[0].transfer(1000, to: amazonAccountID) // ૹۚ੒ޭ maki.bankAccounts.append(ktanaka.bankAccounts[0]) maki.bankAccounts[0].transfer(100_000, to: amazonAccountID) // ૹۚ੒ޭ ktanaka.bankAccounts[0].changePassword(to: “5678") maki.bankAccounts[0].transfer(500_000, to: amazonAccountID) // ૹۚ੒ޭʂʁ ٤ٌڂڋٜ⯪㧕؊㏰❔؄؋
  16. class Human { // … var bankAccounts: [BankAccount] // …

    } protocol BankAccountDelegate: class { func account(_ account: BankAccount, changePasswordTo newPassword: String) throws -> Int func account(_ account: BankAccount, transfer amount: Int, to receiver: Int) throws } class BankAccount { // … func changePassword(to newPassword: String) { // … } func transfer(_ amount: Int, to receiver: Int) { do { guard let delegate = self.delegate else { throw NSError() } try delegate.account(self, transfor: amount, to: receiver) print("ૹۚ੒ޭ") } catch { print("ૹࣦۚഊ") } } } let tanakaAccount = someBank.issueAccount(password: "1234") ktanaka.bankAccounts.append(tanakaAccount) let amazonAccountID = someBank.issueAccount(password: "J7BJuGy8ks2T").id ktanaka.bankAccounts[0].transfer(1000, to: amazonAccountID) // ૹۚ੒ޭ maki.bankAccounts.append(ktanaka.bankAccounts[0]) maki.bankAccounts[0].transfer(100_000, to: amazonAccountID) // ૹۚ੒ޭ ktanaka.bankAccounts[0].changePassword(to: “5678") maki.bankAccounts[0].transfer(500_000, to: amazonAccountID) // ૹۚ੒ޭʂʁ
  17. class Human { // … var bankAccounts: [BankAccount] // …

    } protocol BankAccountDelegate: class { func account(_ account: BankAccount, changePasswordTo newPassword: String) throws -> Int func account(_ account: BankAccount, transfer amount: Int, to receiver: Int) throws } class BankAccount { // … func changePassword(to newPassword: String) { // … } func transfer(_ amount: Int, to receiver: Int) { do { guard let delegate = self.delegate else { throw NSError() } try delegate.account(self, transfor: amount, to: receiver) print("ૹۚ੒ޭ") } catch { print("ૹࣦۚഊ") } } } let tanakaAccount = someBank.issueAccount(password: "1234") ktanaka.bankAccounts.append(tanakaAccount) let amazonAccountID = someBank.issueAccount(password: "J7BJuGy8ks2T").id ktanaka.bankAccounts[0].transfer(1000, to: amazonAccountID) // ૹۚ੒ޭ maki.bankAccounts.append(ktanaka.bankAccounts[0]) maki.bankAccounts[0].transfer(100_000, to: amazonAccountID) // ૹۚ੒ޭ ktanaka.bankAccounts[0].changePassword(to: “5678") maki.bankAccounts[0].transfer(500_000, to: amazonAccountID) // ૹۚ੒ޭʂʁ
  18. class Human { // … var bankAccounts: [BankAccount] // …

    } protocol BankAccountDelegate: class { func account(_ account: BankAccount, changePasswordTo newPassword: String) throws -> Int func account(_ account: BankAccount, transfer amount: Int, to receiver: Int) throws } struct BankAccount { // … func changePassword(to newPassword: String) { // … } func transfer(_ amount: Int, to receiver: Int) { do { guard let delegate = self.delegate else { throw NSError() } try delegate.account(self, transfor: amount, to: receiver) print("ૹۚ੒ޭ") } catch { print("ૹࣦۚഊ") } } } let tanakaAccount = someBank.issueAccount(password: "1234") ktanaka.bankAccounts.append(tanakaAccount) let amazonAccountID = someBank.issueAccount(password: "J7BJuGy8ks2T").id ktanaka.bankAccounts[0].transfer(1000, to: amazonAccountID) // ૹۚ੒ޭ maki.bankAccounts.append(ktanaka.bankAccounts[0]) maki.bankAccounts[0].transfer(100_000, to: amazonAccountID) // ૹۚ੒ޭ ktanaka.bankAccounts[0].changePassword(to: “5678") maki.bankAccounts[0].transfer(500_000, to: amazonAccountID) // ૹࣦۚഊʂ
  19. struct Player { let name: String // ໊લɺมߋෆՄ var level

    = 1 // ͦͷଞॾʑ init(name: String) { self.name = name } mutating func levelUp() { level += 1 } } var player = Player(name: "ྋ෩੨༿") { didSet { // ηʔϒσʔλ } } player.levelUp() // didSet ͕ݺ͹ΕͯϢʔβσʔλ͕ηʔϒ͞ΕΔ
 player = Player(name: "ࡩͶͶ") // ϩδοΫΤϥʔɿఆ਺Ͱ͋Δ player.name ͕มΘͬͯ͠·͏
  20. class Player { struct Status { var level = 1

    // ͦͷଞॾʑ mutating func levelUp() { level += 1 } } let name: String // ໊લɺมߋෆՄ var status = Status() { didSet { // ηʔϒσʔλ } } init(name: String) { self.name = name } } let player = Player(name: "ྋ෩੨༿") player.status.levelUp() // status ͷ didSet ͕ݺ͹ΕͯϢʔβσʔλ͕ηʔϒ͞ΕΔ player = Player(name: "ࡩͶͶ") // Τϥʔɿఆ਺Ͱ͋Δ player ͕࠶୅ೖͰ͖ͳ͍ʢ૝ఆ௨Γಈ࡞ʣ