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
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
520
@Environment(\.keyPath)那么好我不允许你们不知道! / atEnvironment keyPath is so good and you should know it!
lovee
0
530
ゼロから始めるPreferenceの実装 / Let's implement Preferences from scratch
lovee
0
160
Kotlin エンジニアへ送る:Swift 案件に参加させられる日に備えて~似てるけど色々違う Swift の仕様 / from Kotlin to Swift
lovee
1
400
個人アプリを2年ぶりにアプデしたから褒めて / I just updated my personal app, praise me!
lovee
0
770
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
FastAPI の並行処理モデルを完全に理解する
hoto17296
9
3.3k
AI時代に学ぶ 好きなルール 嫌いなルール Linter編
shorty5121
0
660
夏だ!祭りだ!祭りとはドメインモデリングでは?
ryugen04
0
490
業務時間外もAIに働いてもらう話
colorful12
3
9.4k
関東Kaggler会_NVIDIA_Nemotron_コンペ_振り返り
rick_ds
0
760
Webエンジニアなのにブラウザの仕組みがわからないので、Pythonで自作してみた
tatsuki12
4
1.6k
Go 1.27からのGODEBUG / Go 1.27 リリースパーティ #go127party
mazrean
0
270
typoなんかねぇよ
raspython3
0
630
コンパウンドプロダクト開発のためのローカルプロセスマネージャー再発明 #layerxgo
izumin5210
0
600
[PyCon KR 2026] More Variants, More Diversity for AI Accelerators
achimnol
0
130
リアルな遅延を測る仕様
kota_yata
1
130
思考垂れ流し開発 ~音声入力 × AIエージェント × 開発ハーネスによる試行錯誤~
npostring
0
570
Featured
See All Featured
Designing Powerful Visuals for Engaging Learning
tmiket
1
520
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
2
260
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
1k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Are puppies a ranking factor?
jonoalderson
2
3.9k
The Limits of Empathy - UXLibs8
cassininazir
1
620
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.6k
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.6k
ラッコキーワード サービス紹介資料
rakko
1
4.6M
Agile that works and the tools we love
rasmusluckow
331
22k
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4.3k
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ƵĆ -