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
為什麼你並不需要ViewModel / No, you don't need a ViewModel
lovee
1
490
@Environment(\.keyPath)那么好我不允许你们不知道! / atEnvironment keyPath is so good and you should know it!
lovee
0
520
ゼロから始めるPreferenceの実装 / Let's implement Preferences from scratch
lovee
0
150
Kotlin エンジニアへ送る:Swift 案件に参加させられる日に備えて~似てるけど色々違う Swift の仕様 / from Kotlin to Swift
lovee
1
400
個人アプリを2年ぶりにアプデしたから褒めて / I just updated my personal app, praise me!
lovee
0
760
How did I build an Open-Source SwiftUI Toast Library
lovee
1
180
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
450
Other Decks in Programming
See All in Programming
PHP に部分適用が来るぞ!……ところで何それ?おいしいの? #phpcon / phpcon-2026
shogogg
0
640
生成AI導入の「期待外れ」を乗り越える ー 開発フロー改革が目指す、真の組織変革
starfish719
0
4.3k
ルールを書いて終わらせないハーネスエンジニアリング
yug1224
4
1.9k
170k Jobs a Day on GKE: Scaling Mercari's CI Platform - and What's Next for AI-Native Development
junyaokabe
0
110
OpenSpecのproposalにbrainstormingを持たせてみた
tigertora7571
1
220
Android CLI
fornewid
0
220
GDG Korea Android: 2026 I/O Extended ~ What's new in Android development tools
pluu
0
220
今さら聞けない .NET CLI
htkym
0
190
TSX の <Hoge<Fuga>> という構文に驚いた話 / tsx-type-argument-syntax
kanaru0928
0
220
the container ship “Apple Silicon”@WWDC26 Recap -Japan-\(region).swift
shingangan
0
120
いまどきの Codex で開発する visionOS アプリの開発スタイルについて
karad
0
130
Go言語とトイモデルで学ぶTransformerの気持ち / fukuokago23-transformer
monochromegane
0
170
Featured
See All Featured
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
380
Practical Orchestrator
shlominoach
191
12k
The Curious Case for Waylosing
cassininazir
1
450
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
Building AI with AI
inesmontani
PRO
1
1.1k
How to build a perfect <img>
jonoalderson
1
5.9k
First, design no harm
axbom
PRO
2
1.2k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
460
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
3
430
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.7k
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
230
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ƵĆ -