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

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

Af64bc38c0ffcfcabdf430759ee491ce?s=47 Elvis Shi
February 08, 2017

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

Af64bc38c0ffcfcabdf430759ee491ce?s=128

Elvis Shi

February 08, 2017
Tweet

More Decks by Elvis Shi

Other Decks in Programming

Transcript

  1. Struct ͱ Class ͷ࢖͍෼͚ํ ࠓߋฉ͚ͳ͍ʁ

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

    @loveeʢ੕໺ܙྤʣ ͷΞγελϯτP←!!!!
  3. class struct vs

  4. struct class ܕ ஋ܕ ࢀরܕ ܧঝ ෆՄ Մೳ deinit ͳ͠

    ͋Γ
  5. struct class ܕ ஋ܕ ࢀরܕ ܧঝ ෆՄ Մೳ deinit ͳ͠

    ͋Γ ๏ ੜ੒ίετ௿͍ ๏ ॥؀ࢀর໰୊͕ͳ͍ ๏ εϨουηʔϑ ๏ ॲཧ͕୯७Ͱ෼͔Γ΍͍͢ ๏ etc…
  6. ΋͏શ෦ struct ࢖͓͏ͥʂ ʢUIView ͱ͔͔Βܧঝ͢Δ΋ͷҎ֎ʣ

  7. 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 ͕ݺ͹ΕͯϢʔβσʔλ͕ηʔϒ͞ΕΔ
  8. 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 ͕ݺ͹ΕͯϢʔβσʔλ͕ηʔϒ͞ΕΔ
  9. 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 ͕มΘͬͯ͠·͏
  10. 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 ͕มΘͬͯ͠·͏ 㨍㩆㏔⹻׳׻⹪⑉㌈ר挵㓱؃ש؆ק׿׻Ŏ
  11. ΍͸Γ struct ͱ class ͸ ͪΌΜͱ࢖͍෼͚·͠ΐ͏

  12. switch instance { case is Data: useStruct() case is Object:

    useClass() case _: fatalError("ͪΌΜͱߟ͑Ζʂ") } 嗒嵿䥥鰛㏰❔鰘鰟 &CVC鰙1DLGEV鰑鰹
 鱣鱈鱻痓鰉鰴鰛鯵鰹
  13. true false ୅ೖ࣌ʹσʔλͷίϐʔͱͯ͠ ୅ೖ͞ΕΔͷ͕͓͔͍͠ class struct ಉҰൺֱʢ===ʣʹҙຯ͕͋Δ ʮϥΠϑαΠΫϧʯ͕ߟ͑ΒΕ Δ ந৅తͳʮຊମʯ͕ߟ͑ΒΕΔ

  14. 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
  15. 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 ㌬↛؄؋
  16. 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
  17. true false ୅ೖ࣌ʹσʔλͷίϐʔͱͯ͠ ୅ೖ͞ΕΔͷ͕͓͔͍͠ class struct ಉҰൺֱʢ===ʣʹҙຯ͕͋Δ ʮϥΠϑαΠΫϧʯ͕ߟ͑ΒΕ Δ ந৅తͳʮຊମʯ͕ߟ͑ΒΕΔ

    " " " "
  18. 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
  19. 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
  20. 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("ૹࣦۚഊ") } } }
  21. 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) // ૹۚ੒ޭʂʁ
  22. 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) // ૹۚ੒ޭʂʁ ٤ٌڂڋٜ⯪㧕؊㏰❔؄؋
  23. 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) // ૹۚ੒ޭʂʁ
  24. true false ୅ೖ࣌ʹσʔλͷίϐʔͱͯ͠ ୅ೖ͞ΕΔͷ͕͓͔͍͠ class struct ಉҰൺֱʢ===ʣʹҙຯ͕͋Δ ʮϥΠϑαΠΫϧʯ͕ߟ͑ΒΕ Δ ந৅తͳʮຊମʯ͕ߟ͑ΒΕΔ

    # # # #
  25. 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) // ૹۚ੒ޭʂʁ
  26. 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) // ૹࣦۚഊʂ
  27. 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 ͕มΘͬͯ͠·͏
  28. 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 ͕࠶୅ೖͰ͖ͳ͍ʢ૝ఆ௨Γಈ࡞ʣ
  29. 㛀źŧ4XJGU8JGFƵĆ -