Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
今更聞けない?Struct と class の使い分け方
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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
@Environment(\.keyPath)那么好我不允许你们不知道! / atEnvironment keyPath is so good and you should know it!
lovee
0
500
ゼロから始めるPreferenceの実装 / Let's implement Preferences from scratch
lovee
0
150
Kotlin エンジニアへ送る:Swift 案件に参加させられる日に備えて~似てるけど色々違う Swift の仕様 / from Kotlin to Swift
lovee
1
390
個人アプリを2年ぶりにアプデしたから褒めて / I just updated my personal app, praise me!
lovee
0
750
How did I build an Open-Source SwiftUI Toast Library
lovee
1
170
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
440
ChatGPT 時代の勉強 / Learning under ChatGPT era
lovee
27
9k
Other Decks in Programming
See All in Programming
광주소프트웨어마이스터고등학교 DevFest 특강 - 바이브 코딩 시대에서 주니어 개발자로 살아남는 방법
utilforever
1
150
SREは、MCPとSRE Agentをこう使え!
kazumax55
0
150
音楽のための関数型プログラミング言語mimiumにおける多段階計算の活用
tomoyanonymous
1
350
型も通る、synthも通る、それでも危ない 〜AIのCDKの権限とコストを機械で検証する〜 / It Passes Type Checks, It Passes Synth Checks, but It’s Still Risky — Automatically Verifying Permissions and Costs in AI’s CDK —
seike460
PRO
1
400
ルールを書いて終わらせないハーネスエンジニアリング
yug1224
4
1.7k
関数型プログラミングのメリットって何だろう?
wanko_it
0
190
SREの積み重ねがAI駆動開発のガードレールになった ― 7つの実践/SRE Guardrails The 7
tomoyakitaura
8
5.1k
エンジニア向け会社紹介/Findy Company Profile
findyinc
6
360k
Go言語とトイモデルで学ぶTransformerの気持ち / fukuokago23-transformer
monochromegane
0
140
生成AI導入の「期待外れ」を乗り越える ー 開発フロー改革が目指す、真の組織変革
starfish719
0
1.6k
【やさしく解説 設計編・中級 #4】ルールの寿命と、システムの年輪
panda728
PRO
2
160
えっ!!コードを読まずに開発を!?
hananouchi
0
230
Featured
See All Featured
RailsConf 2023
tenderlove
30
1.5k
Build your cross-platform service in a week with App Engine
jlugia
234
18k
エンジニアに許された特別な時間の終わり
watany
108
250k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
190
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
WENDY [Excerpt]
tessaabrams
11
38k
The Pragmatic Product Professional
lauravandoore
37
7.4k
The Mindset for Success: Future Career Progression
greggifford
PRO
0
430
4 Signs Your Business is Dying
shpigford
187
22k
Product Roadmaps are Hard
iamctodd
55
12k
Amusing Abliteration
ianozsvald
1
240
For a Future-Friendly Web
brad_frost
183
10k
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ƵĆ -