Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
今更聞けない?Struct と class の使い分け方
Search
Elvis Shi
February 08, 2017
Programming
3.6k
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
今更聞けない?Struct と class の使い分け方
Elvis Shi
February 08, 2017
More Decks by Elvis Shi
See All by Elvis Shi
為什麼你並不需要ViewModel / No, you don't need a ViewModel
lovee
1
570
@Environment(\.keyPath)那么好我不允许你们不知道! / atEnvironment keyPath is so good and you should know it!
lovee
0
570
ゼロから始めるPreferenceの実装 / Let's implement Preferences from scratch
lovee
0
160
Kotlin エンジニアへ送る:Swift 案件に参加させられる日に備えて~似てるけど色々違う Swift の仕様 / from Kotlin to Swift
lovee
1
410
個人アプリを2年ぶりにアプデしたから褒めて / I just updated my personal app, praise me!
lovee
0
790
How did I build an Open-Source SwiftUI Toast Library
lovee
1
190
SwiftUIで使いやすいToastの作り方 / How to build a Toast system which is easy to use in SwiftUI
lovee
3
1.3k
SwiftUIで二重スクロール作ってみた / When I tried to make a dual-scroll-ish view in SwiftUI
lovee
1
390
Observation のあれこれ / A brief introduction about Observation
lovee
3
460
Other Decks in Programming
See All in Programming
月間100万人のサービス刷新で、 技術選定をHonoに振り切った話
yutobara
6
4.8k
iOS 27でニュースアプリはどう変わる!? 〜日経電子版の新機能対応と、開発事例から〜
lynnswap
7
13k
UPDATE をやめる — EF Core でマスタをバージョン管理する
panda728
PRO
0
1.1k
The Rails Doctrine Decade
koic
2
520
FreeBSDでZabbixを動かす
kenkino
0
360
Turning Architecture into Unit Tests in the AI Era (NSSpain XIV)
steliosf
PRO
1
130
Are APIs Still Relevant in the AI Era?
soyuka
0
440
技術的負債の返済は、AI時代の複利で効く投資 — 経営としての意思決定とその遂行
curekoshimizu
1
2.2k
更なる可用性を求めて、5年間運用したKotlinのアプリケーションをGoでリプレイスする話
ken_tunc
0
450
最近”作らせてる” ローカルAIアプリの話
akit37
0
310
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
570
Vue Fes Japan の “作る側”に関わってみて
naokihaba
0
130
Featured
See All Featured
What does AI have to do with Human Rights?
axbom
PRO
1
2.4k
A Soul's Torment
seathinner
8
3.7k
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
350
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.4k
We Are The Robots
honzajavorek
0
390
HDC tutorial
michielstock
2
950
Mind Mapping
helmedeiros
1
390
For a Future-Friendly Web
brad_frost
184
10k
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
620
Claude Code のすすめ
schroneko
67
230k
Bootstrapping a Software Product
garrettdimon
PRO
306
120k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
490
Transcript
Struct ͱ Class ͷ͍͚ํ ࠓߋฉ͚ͳ͍ʁ
Who am I? MAGES. Inc. Game Div. (5pb.Games) iOS Developer
@loveeʢܙྤʣ ͷΞγελϯτP←!!!!
class struct vs
struct class ܕ ܕ ࢀরܕ ܧঝ ෆՄ Մೳ deinit ͳ͠
͋Γ
struct class ܕ ܕ ࢀরܕ ܧঝ ෆՄ Մೳ deinit ͳ͠
͋Γ ๏ ੜίετ͍ ๏ ॥ࢀর͕ͳ͍ ๏ εϨουηʔϑ ๏ ॲཧ͕୯७Ͱ͔Γ͍͢ ๏ etc…
͏શ෦ struct ͓͏ͥʂ ʢUIView ͱ͔͔Βܧঝ͢ΔͷҎ֎ʣ
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 ͕ݺΕͯϢʔβσʔλ͕ηʔϒ͞ΕΔ
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 ͕ݺΕͯϢʔβσʔλ͕ηʔϒ͞ΕΔ
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 ͕มΘͬͯ͠·͏
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 ͕มΘͬͯ͠·͏ 㨍㩆㏔׳⑉㌈ר挵㓱ש؆קŎ
Γ struct ͱ class ͪΌΜͱ͍͚·͠ΐ͏
switch instance { case is Data: useStruct() case is Object:
useClass() case _: fatalError("ͪΌΜͱߟ͑Ζʂ") } 嗒嵿䥥鰛㏰❔鰘鰟 &CVC鰙1DLGEV鰑鰹 鱣鱈鱻痓鰉鰴鰛鯵鰹
true false ೖ࣌ʹσʔλͷίϐʔͱͯ͠ ೖ͞ΕΔͷ͕͓͔͍͠ class struct ಉҰൺֱʢ===ʣʹҙຯ͕͋Δ ʮϥΠϑαΠΫϧʯ͕ߟ͑ΒΕ Δ நతͳʮຊମʯ͕ߟ͑ΒΕΔ
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
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 ㌬↛؋
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
true false ೖ࣌ʹσʔλͷίϐʔͱͯ͠ ೖ͞ΕΔͷ͕͓͔͍͠ class struct ಉҰൺֱʢ===ʣʹҙຯ͕͋Δ ʮϥΠϑαΠΫϧʯ͕ߟ͑ΒΕ Δ நతͳʮຊମʯ͕ߟ͑ΒΕΔ
" " " "
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
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
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("ૹࣦۚഊ") } } }
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) // ૹۚޭʂʁ
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) // ૹۚޭʂʁ ٤ٌڂڋٜ⯪㧕؊㏰❔؋
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) // ૹۚޭʂʁ
true false ೖ࣌ʹσʔλͷίϐʔͱͯ͠ ೖ͞ΕΔͷ͕͓͔͍͠ class struct ಉҰൺֱʢ===ʣʹҙຯ͕͋Δ ʮϥΠϑαΠΫϧʯ͕ߟ͑ΒΕ Δ நతͳʮຊମʯ͕ߟ͑ΒΕΔ
# # # #
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) // ૹۚޭʂʁ
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) // ૹࣦۚഊʂ
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 ͕มΘͬͯ͠·͏
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 ͕࠶ೖͰ͖ͳ͍ʢఆ௨Γಈ࡞ʣ
㛀źŧ4XJGU8JGFƵĆ -