Swiftã®åºæ¬çãªæŠå¿µã«ã€ããŠåŠã³ãããŒã¿ç«¶åã®ãªã䞊è¡ã³ãŒããå®çŸããæ¹æ³ãç¥ããŸãããã
åæ | https://github.com/apple/swift-migration-guide/blob/main/Guide.docc/DataRaceSafety.md |
---|---|
æŽæ°æ¥ | 2024/7/6(翻蚳ãæåŸã«æŽæ°ããæ¥ä») |
ãããŸã§åæ | https://github.com/apple/swift-migration-guide/commit/24e31ffc589fefb42f08877878e689eb29b1644b |
åŸæ¥ãå¯å€ç¶æ
(mutable state)ã¯ã现å¿ã®æ³šæãæããå®è¡æã®åæã«ãã£ãŠæåã§ä¿è·ããå¿
èŠããããŸããã
ã€ãŸããããã¯ããã¥ãŒãªã©ã®ããŒã«ã䜿çšããŠãããŒã¿ç«¶åãé²ãå®å
šã«ããã°ã©ããŒä»»ãã§ããããã¯ãæ£ããå®è¡ããã ãã§ãªãããã£ãšæ£ããå®è¡ãç¶ããããšãéåžžã«é£ãããã®ã§ãã
åæã®å¿
èŠæ§ãå€æããããšããé£ãããããããŸããã
ææªãªã®ã¯ãå®å
šã§ãªãã³ãŒãã§ã¯å®è¡æã«å€±æãä¿èšŒãããªãããšã§ãã
ãã®ã³ãŒãã¯å€ãã®å Žåã¯æ£ããåããŠããããã«èŠããŸãããããã¯ãããããããŒã¿ç«¶åã®ç¹åŸŽã§ããäžæ£ç¢ºã§äºæž¬äžå¯èœãªæåãè¡šé¢åããã®ã«ã¯ããªãç¹æ®ãªæ¡ä»¶ãå¿
èŠã«ãªãããã§ãããã
ããæ£ç¢ºã«ãããšãããŒã¿ç«¶åã¯ãããã¹ã¬ãããã¡ã¢ãªã«ã¢ã¯ã»ã¹ããŠããéã«ãå¥ã®ã¹ã¬ãããåãã¡ã¢ãªãå€æŽããããšã§çºçããŸãã Swift 6ã®èšèªã¢ãŒãã¯ãã³ã³ãã€ã«æã«ããŒã¿ã¬ãŒã¹ãé²ãããšã«ãã£ãŠããããã®åé¡ãæé€ããŸãã
éèŠ: ä»ã®èšèªã§
async
/await
ãã¢ã¯ã¿ãŒã®ãããªæ§é ã«ééããããšããããããããŸãããSwiftã®ãããã®æŠå¿µãšã®é¡äŒŒæ§ã¯è¡šé¢çãªãã®ã§ãããªããããããªãã®ã§ãç¹ã«æ³šæããŠãã ããã
Swiftã®äžŠè¡åŠçã·ã¹ãã ã¯ãã³ã³ãã€ã©ããã¹ãŠã®å¯å€ç¶æ
ã®å®å
šæ§ãç解ããæ€èšŒããããšãå¯èœã«ããŸãã
ããã¯ãããŒã¿éé¢ãšåŒã°ããä»çµã¿ã§å®çŸãããŠããŸããããŒã¿éé¢ã¯ãå¯å€ç¶æ
ãžã®çžäºæä»çãªã¢ã¯ã»ã¹ãä¿èšŒããŸããããã¯ãåæã®äžåœ¢æ
ã§ãããæŠå¿µçã«ã¯ããã¯ã«äŒŒãŠããŸããããããããã¯ãšã¯ç°ãªããããŒã¿éé¢ãæäŸããä¿è·ã¯ä»¥äžã®å Žæã§èµ·ãããŸãã<
Swiftããã°ã©ããŒã¯ãéçãšåçãšãã2ã€ã®æ¹æ³ã§ããŒã¿ãéé¢ããŸãïŒ
éçãšããçšèªã¯ãå®è¡æã®ç¶æ ã«åœ±é¿ãããªãããã°ã©ã èŠçŽ ãèšè¿°ããããã«äœ¿çšãããŸããé¢æ°å®çŸ©ã®ãããªãããã®èŠçŽ ã¯ãããŒã¯ãŒããšã¢ãããŒã·ã§ã³ã§æ§æãããŠããŸããSwiftã®äžŠè¡åŠçã·ã¹ãã ã¯ãåã·ã¹ãã ãæ¡åŒµãããã®ã§ããé¢æ°ãšåã宣èšãããšãã¯ãéçã«è¡ãªããŸããããŒã¿éé¢ã¯ããããã®éç宣èšã®äžéšã«ãªãå ŽåããããŸãã
ãã ããåã·ã¹ãã ã ãã§ã¯ãå®è¡æã®æåãååã«èª¬æã§ããªãå ŽåããããŸããäŸãšããŠã¯ãSwiftã«å ¬éãããŠããObjective-Cã®åãæããããŸããSwiftã³ãŒãã®å€éšã§è¡ãªããããã®å®£èšã§ã¯ãå®å šãªäœ¿çšãä¿èšŒããããã«ã³ã³ãã€ã©ã«ååãªæ å ±ãæäŸãããªãå Žåãããã®ã§ãããã®ãããªç¶æ³ã«å¯Ÿå¿ããããã«ãããŒã¿éé¢ã®èŠä»¶ãåçã«è¡šçŸã§ããè¿œå æ©èœããããŸãã
ããŒã¿éé¢ã¯ãéçã§ããåçã§ãããã³ã³ãã€ã©ãããªãã®æžããSwiftã³ãŒãã«ããŒã¿ç«¶åããªãããšãä¿èšŒããŸãã
泚èš: åçãªéé¢ã«ã€ããŠã®è©³çŽ°ã¯ãIncrementalAdoptionãåç §ããŠãã ããã
ããŒã¿ã®éé¢ã¯ãå ±æå¯å€ç¶æ (shared mutable state)ãä¿è·ããããã®ä»çµã¿ã§ãããã ããç¬ç«ããåã ã®éé¢åäœã«ã€ããŠè©±ããšåœ¹ã«ç«ã€ããšããããããŸããããã¯éé¢ãã¡ã€ã³ãšåŒã°ããŸããç¹å®ã®ãã¡ã€ã³ãä¿è·ããç¶æ ã®ç¯å²ã¯ã倧ããç°ãªããŸããéé¢ãã¡ã€ã³ã¯ãåäžã®å€æ°ãä¿è·ããããšãããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹ã®ãããªãµãã·ã¹ãã å šäœãä¿è·ããããšããããŸãã
éé¢ãã¡ã€ã³ã®éèŠãªç¹åŸŽã¯ããããæäŸããå®å šæ§ã§ããå¯å€ç¶æ ã¯äžåºŠã«1ã€ã®éé¢ãã¡ã€ã³ããã®ã¿ã¢ã¯ã»ã¹ã§ããŸããããéé¢ãã¡ã€ã³ããå¥ã®éé¢ãã¡ã€ã³ã«å¯å€ç¶æ ãæž¡ããŸãããå¥ã®ãã¡ã€ã³ãããã®ç¶æ ã«åæã«ã¢ã¯ã»ã¹ããããšã¯æ±ºããŠã§ããŸãããã³ã³ãã€ã©ãããããä¿èšŒãããŠãããããæ€èšŒããŸãã
ããšãèªåã§æ瀺çã«å®çŸ©ããŠããªããŠãããã¹ãŠã®é¢æ°ãå€æ°ã®å®£èšã«ã¯ãæ確ã«å®çŸ©ãããéçãªéé¢ãã¡ã€ã³ãååšããŸãããããã®ãã¡ã€ã³ã¯åžžã«3ã€ã®ã«ããŽãªã®ãã¡ã®1ã€ã«åé¡ãããŸãã
- ééé¢(Non-isolated)
- ã¢ã¯ã¿ãŒã«éé¢ãããŠãã
- ã°ããŒãã«ã¢ã¯ã¿ãŒã«éé¢ãããŠãã
é¢æ°ãå€æ°ã¯æ瀺çãªéé¢ãã¡ã€ã³ã«ã®äžéšã§ããå¿ èŠã¯ãããŸãããå®éãéé¢ãããŠããªãã®ãããã©ã«ãã§ã*ééé¢(non-isolated)*ãšåŒã°ããŸããã€ãŸãããã¹ãŠã®ããŒã¿éé¢ã®ã«ãŒã«ãé©çšããããããééé¢ã®ã³ãŒããå¥ã®ãã¡ã€ã³ã§ä¿è·ãããŠããç¶æ ã«å€æŽããããšã¯ã§ããŸããã
func sailTheSea() {
}
ãã®ãããã¬ãã«é¢æ°ã¯éçã«éé¢ãããŠããªããããééé¢ã§ããä»ã®åééé¢ã®é¢æ°ãå®å šã«åŒã³åºããããééé¢ã®å€æ°ã«ã¢ã¯ã»ã¹ã§ããŸãããä»ã®éé¢ãã¡ã€ã³ã«ååšãããã®ã«ã¯äœãã¢ã¯ã»ã¹ã§ããŸããã
class Chicken {
let name: String
var currentHunger: HungerLevel
}
ããã¯ãééé¢åã®äŸã§ããç¶æ¿ã¯ãéçãªéé¢ãåŒãç¶ããŸããããããã¹ãŒããŒã¯ã©ã¹ããããã³ã«æºæ ããªããã®åçŽãªã¯ã©ã¹ã¯ãããã©ã«ãã®éé¢ã䜿çšããŠããŸãã
ããŒã¿éé¢ã¯ãééé¢ã®ååšããä»ã®ãã¡ã€ã³ããå¯å€ç¶æ ã«ã¢ã¯ã»ã¹ã§ããªãããšãä¿èšŒããŸãããã®çµæãééé¢ã®é¢æ°ãå€æ°ã¯ãä»ã®ãã¡ã€ã³ããã¢ã¯ã»ã¹ããŠãåžžã«å®å šã§ãã
ã¢ã¯ã¿ãŒã¯ãããã°ã©ããŒã«ããã®ãã¡ã€ã³å ã§åäœããã¡ãœãããšãšãã«ãéé¢ãã¡ã€ã³ãå®çŸ©ããæ¹æ³ãæäŸããŸããã¢ã¯ã¿ãŒã®æ ŒçŽããããã£ã¯ãã¹ãŠãããããå²ãã¢ã¯ã¿ãŒã€ã³ã¹ã¿ã³ã¹ã«éé¢ãããŸãã
actor Island {
var flock: [Chicken]
var food: [Pineapple]
func addToFlock() {
flock.append(Chicken())
}
}
ããã§ããã¹ãŠã®Island
ã€ã³ã¹ã¿ã³ã¹ã¯ããã®ããããã£ãžã®ã¢ã¯ã»ã¹ãä¿è·ããããã«äœ¿çšãããæ°ãããã¡ã€ã³ãå®çŸ©ããŸããã¡ãœããIsland.addToFlock
ã¯self
ã«éé¢ãããŠãããšèšãããŸããã¡ãœããæ¬äœã¯ããã®éé¢ãã¡ã€ã³ãå
±æãããã¹ãŠã®ããŒã¿ã«ã¢ã¯ã»ã¹ã§ããflock
ããããã£ã«åæçã«ã¢ã¯ã»ã¹ã§ããŸãã
ã¢ã¯ã¿ãŒã®éé¢ã¯ãéžæçã«ç¡å¹ã«ã§ããŸããããã¯ãéé¢ãããåã®ãªãã§ã³ãŒããæŽçãããããã©ããããã«äŒŽãéé¢ã®èŠä»¶ã¯é¿ããããšããå Žåã«äŸ¿å©ã§ããééé¢ã¡ãœããã¯ä¿è·ãããç¶æ ã«ãåæçã«ã¢ã¯ã»ã¹ããããšã¯ã§ããŸããã
actor Island {
var flock: [Chicken]
var food: [Pineapple]
nonisolated func canGrow() -> PlantSpecies {
// neither flock nor food are accessible here
}
}
ã¢ã¯ã¿ãŒã®éé¢ãã¡ã€ã³ã¯ãããèªèº«ã®ã¡ãœããã«éå®ãããŸãããéé¢ããããã©ã¡ãŒã¿ãåãåãé¢æ°ã¯ãä»ã®åœ¢åŒã®åæãå¿ èŠãšããã«ãã¢ã¯ã¿ãŒãéé¢ããç¶æ ã«ã¢ã¯ã»ã¹ã§ããããã«ããŸãã
func addToFlock(of island: isolated Island) {
island.flock.append(Chicken())
}
泚èš: ã¢ã¯ã¿ãŒã®æŠèŠã«ã€ããŠã¯ãThe Swift Programming Language ã® Actors ã»ã¯ã·ã§ã³ãåç §ããŠãã ããã
ã°ããŒãã«ã¢ã¯ã¿ãŒã¯ãéåžžã®ã¢ã¯ã¿ãŒã®ç¹æ§ããã¹ãŠæã¡ãŸããã宣èšã®éé¢ãã¡ã€ã³ãéçã«å²ãåœãŠãæ段ãæäŸããŸããããã¯ãã¢ã¯ã¿ãŒåãšäžèŽããã¢ãããŒã·ã§ã³ãã€ããããšã«ãã£ãŠè¡ãªãããŸããã°ããŒãã«ã¢ã¯ã¿ãŒã¯ãããã«å«ãŸãããã¹ãŠã®ãã®ããå ±æå¯å€ç¶æ ãæ±ãåäžã®éé¢ãã¡ã€ã³ã®ãªãã§åæã«äœ¿çšããå¿ èŠãããå Žåã«ç¹ã«äŸ¿å©ã§ãã
@MainActor
class ChickenValley {
var flock: [Chicken]
var food: [Pineapple]
}
ãã®ã¯ã©ã¹ã¯MainActor
ã«å¯ŸããŠéçã«éé¢ãããŠããŸããããã«ããããã®å¯å€ç¶æ
ãžã®ãã¹ãŠã®ã¢ã¯ã»ã¹ãããã®éé¢ãã¡ã€ã³ããè¡ãªãããããã«ãªããŸãã
nonisolated
ããŒã¯ãŒãã䜿çšããããšã§ããã®åã®ã¢ã¯ã¿ãŒã®éé¢ããªããã¢ãŠãã§ããŸãããããŠãä»ã®ã¢ã¯ã¿ãŒãšåæ§ã«ãããããããšã§ä¿è·ãããç¶æ
ãžã®ã¢ã¯ã»ã¹ã¯ã§ããªããªããŸãã
@MainActor
class ChickenValley {
var flock: [Chicken]
var food: [Pineapple]
nonisolated func canGrow() -> PlantSpecies {
// flockãfoodããã®ä»ã®MainActorã«éé¢ãããç¶æ
ã«ã¯ã¢ã¯ã»ã¹ã§ããªã
}
}
ã¿ã¹ã¯ã¯ãããã°ã©ã å ã§äžŠè¡ããŠå®è¡ã§ããäœæ¥ã®åäœã§ããã¿ã¹ã¯ã®å€åŽã§ãSwiftã¯äžŠè¡ã³ãŒããå®è¡ã§ããŸããããããã¯åžžã«æåã§éå§ããªããã°ãªããªããšããããšã§ã¯ãããŸãããäžè¬çã«ãéåæé¢æ°ã¯ãããããå®è¡ããŠããã¿ã¹ã¯ãèªèããå¿ èŠã¯ãããŸãããå®éãã¿ã¹ã¯ã¯ãå€ãã®å Žåãã¢ããªã±ãŒã·ã§ã³ãã¬ãŒã ã¯ãŒã¯å ããããã¯ããã°ã©ã ã®ãšã³ããªãŒãã€ã³ããšãã£ããããé«ã¬ãã«ã§éå§ã§ããŸãã
Task {
flock.map(Chicken.produce)
}
ã¿ã¹ã¯ã¯ãåžžã«ããéé¢ãã¡ã€ã³ã®ãªãã§å®è¡ãããŸããã¿ã¹ã¯ã¯ãããã¢ã¯ã¿ãŒã€ã³ã¹ã¿ã³ã¹ãã°ããŒãã«ã¢ã¯ã¿ãŒã«éé¢ãããããšãããã°ãééé¢ã§ãã(ã°ããŒãã«ãªéé¢ãã¡ã€ã³ã䜿çšãã)ããšããããŸãããã®éé¢ã¯ãæåã§äœããŸãããã³ã³ããã¹ãã«åºã¥ããŠèªåçã«ç¶æ¿ã§ããŸããã¿ã¹ã¯ã®éé¢ã¯ãä»ã®ãã¹ãŠã®Swiftã³ãŒããšåæ§ã«ãã¿ã¹ã¯ãã¢ã¯ã»ã¹ã§ããå¯å€ç¶æ ã決å®ããŸãã
ã¿ã¹ã¯ã¯åæãšéåæã®äž¡æ¹ã®ã³ãŒããå®è¡ã§ããŸããããããæ§é ãã¿ã¹ã¯ã®æ°ã«é¢ä¿ãªããåãéé¢ãã¡ã€ã³å ã®é¢æ°ã¯ããäºãã«åæã«å®è¡ã§ããŸãããä»»æã®éé¢ãã¡ã€ã³ã§åæã³ãŒããå®è¡ããã¿ã¹ã¯ã¯1ã€ã ãã§ãã
泚èš: ããã«è©³çŽ°ã¯The Swift Programming Languageã®Tasksã»ã¯ã·ã§ã³ãåç §ããŠãã ããã
éé¢ãæ瀺çã«æå®ããæ¹æ³ã¯ãããããããŸãããããã宣èšã®ã³ã³ããã¹ããéé¢ã®ç¶æ¿ã«ãã£ãŠæé»çã«éé¢ãã¡ã€ã³ãæ§ç¯ããŸãã
ãµãã¯ã©ã¹ã¯åžžã«èŠªã¯ã©ã¹ãšåãéé¢ãæã¡ãŸãã
@MainActor
class Animal {
}
class Chicken: Animal {
}
Chicken
ã¯Animal
ãç¶æ¿ããŠãããããAnimal
åã®éçãªéé¢ãæé»çã«é©çšãããŸããããã ãã§ãªãããµãã¯ã©ã¹ã«ãã£ãŠå€æŽããããšãã§ããŸããããã¹ãŠã®Animal
ã€ã³ã¹ã¿ã³ã¹ã¯MainActor
ã«éé¢ãããŠããããšã宣èšãããŠããããã¹ãŠã®Chicken
ã€ã³ã¹ã¿ã³ã¹ãããã§ãªããã°ãªããªããšããããšã§ãã
åã®éçãªéé¢ã¯ãããã©ã«ãã§ãã®ããããã£ãšã¡ãœããã«å¯ŸããŠãæšè«ãããŸãã
@MainActor
class Animal {
// all declarations within this type are also
// implicitly MainActor-isolated
let name: String
func eat(food: Pineapple) {
}
}
泚èš: ããã«è©³çŽ°ã«ã€ããŠã¯ãThe Swift Programming Languageã®Inheritanceã»ã¯ã·ã§ã³ãåç §ããŠãã ããã
ãããã³ã«ãžã®æºæ ã¯ãæé»çã«éé¢ã«åœ±é¿ãäžããŸãããããããããã³ã«ãéé¢ã«äžãã圱é¿ã¯ããã®æºæ ãé©çšãããå Žæã«äŸããŸãã
@MainActor
protocol Feedable {
func eat(food: Pineapple)
}
// æšè«ãããéé¢ã¯åå
šäœã«é©çšããã
class Chicken: Feedable {
}
// æšè«ãããéé¢ã¯ããã®extensionã®äžã®ã¿ã«é©çšããã
extension Pirate: Feedable {
}
ãããã³ã«ã®èŠä»¶ãã®ãã®ãéé¢ã§ããŸããããã«ãããæºæ ããåã«å¯Ÿããéé¢ãã©ã®ããã«æšè«ããããããã现ããå¶åŸ¡ã§ããŸãã
protocol Feedable {
@MainActor
func eat(food: Pineapple)
}
ãããã³ã«ãã©ã®ããã«å®çŸ©ãããæºæ ãè¿œå ããããã«é¢ããããéçãªéé¢ã®ä»ã®ã¡ã«ããºã ãå€æŽã§ããŸãããã€ãŸããããåãæ瀺çã«ããããã¯ã¹ãŒããŒã¯ã©ã¹ããã®æšè«ã«ãã£ãŠã°ããŒãã«ã«éé¢ãããŠããå Žåããããã³ã«æºæ ã䜿ã£ãŠãããå€æŽã§ããªããšããããšã§ãã
泚èš: ããã«è©³çŽ°ã«ã€ããŠã¯ãThe Swift Programming Languageã®Protocolsã»ã¯ã·ã§ã³ãåç §ããŠãã ããã
éé¢ã®æšè«ã¯ãåããã®ããããã£ãšã¡ãœããã®éé¢ãæé»çã«å®çŸ©ããããšãå¯èœã«ããŸãããããããããã¯ãã¹ãŠå®£èšã®äŸã§ããéé¢ã®ç¶æ¿ã§ãã£ãŠããé¢æ°å€ã§åæ§ã®å¹æãåŸãããŸãã
ã¯ããŒãžã£ã¯ãåã«ãã£ãŠéé¢ãéçã«å®çŸ©ããã代ããã«ããã®å®£èšãããå Žæã§éé¢ããã£ããã£ã§ããŸãããã®ã¡ã«ããºã ã¯è€éã«èããããããããŸããããå®éã«ã¯éåžžã«èªç¶ãªæ¯ãèããå¯èœã«ããŸãã
@MainActor
func eat(food: Pineapple) {
// ãã®é¢æ°ã®å®£èšã®éçãªéé¢ã¯ãããã§äœæãããã¯ããŒãžã£ã«ãã£ãŠãã£ããã£ããã
Task {
// ã¯ããŒãžã£å
ã¯MainActorã®éé¢ãç¶æ¿ã§ãã
Chicken.prizedHen.eat(food: food)
}
}
ããã§ã®ã¯ããŒãžã£ã®åã¯Task.init
ã«ãã£ãŠå®çŸ©ãããŠããŸãããã®å®£èšã¯ã©ã®ã¢ã¯ã¿ãŒã«ãéé¢ãããŠããŸãããããã®æ°ããäœæãããã¿ã¹ã¯ã¯ããããå²ãã¹ã³ãŒãã® MainActor
ã®éé¢ãç¶æ¿ããŸãã
é¢æ°åã¯ãéé¢ã®åäœãå¶åŸ¡ããããã®ããŸããŸãªã¡ã«ããºã ãæäŸããŸãããããã©ã«ãã§ã¯ä»ã®åãšåãããã«åäœããŸãã
泚èš: ããã«è©³çŽ°ã«ã€ããŠã¯ãThe Swift Programming Languageã®[Closures][]ã»ã¯ã·ã§ã³ãåç §ããŠãã ããã
éé¢ãã¡ã€ã³ã¯ãå¯å€ç¶æ
ãä¿è·ããŸããããããæçšãªããã°ã©ã ã«ã¯ãä¿è·ä»¥äžã®ãã®ãå¿
èŠã§ããå€ãã®å ŽåãããŒã¿ã®åãæž¡ãã«ãã£ãŠéä¿¡ããå調ããå¿
èŠããããŸããéé¢ãã¡ã€ã³ãžå€ã移åããããéé¢ãã¡ã€ã³ããå€ã移åãããããããšã¯ãéé¢å¢çãè¶ãããšåŒã°ããŸãã
å€ãéé¢å¢çãè¶ããããšãèš±ãããã®ã¯ãå
±æå¯å€ç¶æ
ãžã®åæã¢ã¯ã»ã¹ã®å¯èœæ§ããªãå Žåã®ã¿ã§ãã
å€ã¯ãéåæé¢æ°ã®åŒã³åºããä»ããŠãçŽæ¥å¢çãè¶ããããšãããŸããç°ãªãéé¢ãã¡ã€ã³ã§éåæé¢æ°ãåŒã³åºãå Žåããã©ã¡ãŒã¿ãšæ»ãå€ã¯ããã¡ã€ã³éã移åããããšãå¿ èŠã§ãããŸããå€ãã¯ããŒãžã£ã«ãã£ãŠãã£ããã£ãããå Žåãéæ¥çã«å¢çãè¶ããããšããããŸããã¯ããŒãžã£ã¯éé¢å¢çãè¶ããå€ãã®æœåšçãªå¯èœæ§ããããŸããã¯ããŒãžã£ã¯ããããã¡ã€ã³ã§äœæãããå¥ã®ãã¡ã€ã³ã§å®è¡ãããå¯èœæ§ããããŸããããã«ãè€æ°ã®ç°ãªããã¡ã€ã³ã§å®è¡ãããããšãããããåŸãã®ã§ãã
å Žåã«ãã£ãŠã¯ãã¹ã¬ããã»ãŒãã¯åèªäœã®ç¹æ§ã§ãããããç¹å®ã®åã®ãã¹ãŠã®å€ã¯ãéé¢å¢çãè¶ããŠå®å
šã«æž¡ããŸããããã¯ãSendable
ãããã³ã«ã«æºæ ããããšã§è¡šãããŸããSendable
ã«æºæ ããŠããå Žåããã®ç¹å®ã®åãã¹ã¬ããã»ãŒãã§ããããã®åã®å€ãããŒã¿ç«¶åã®ãªã¹ã¯ãªãã«ä»»æã®éé¢ãã¡ã€ã³éã§å
±æã§ããããšãæå³ããŸãã
Swiftã§ã¯ãå€å(value type)ãæ¬è³ªçã«å®å
šã§ããããããã®äœ¿çšãæšå¥šãããŠããŸããå€åã䜿çšãããšãããã°ã©ã ã®ããŸããŸãªéšåã§ãåãå€ãžã®åç
§ãå
±æã§ããŸãããå€åã®ã€ã³ã¹ã¿ã³ã¹ãé¢æ°ã«æž¡ããšãé¢æ°ã¯ãã®å€ã®ç¬ç«ããã³ããŒãä¿æããŸããå€ã®ã»ãã³ãã£ã¯ã¹ã«ãã£ãŠå
±æå¯å€ç¶æ
ãååšããªãããšãä¿èšŒããããããSwiftã®å€åã¯ãæ ŒçŽãããŠãããã¹ãŠã®ããããã£ãSendable
ã§ããå Žåãæé»çã«Sendable
ã«ãªããŸãããã ãããã®æé»ã®æºæ ã¯ãå®çŸ©ãããã¢ãžã¥ãŒã«ã®å€éšã«ã¯é©çšãããŸãããã¯ã©ã¹ãSendable
ã«ããããšã¯ããã®ãããªãã¯APIã®å¥çŽã®äžéšã§ãããåžžã«æ瀺çã«è¡ãªãå¿
èŠããããŸãã
enum Ripeness {
case hard
case perfect
case mushy(daysPast: Int)
}
struct Pineapple {
var weight: Double
var ripeness: Ripeness
}
ããã§ãRipeness
ãšPineapple
ã®äž¡åã¯ãSendable
ã®å€åã ãã§æ§æãããŠããã®ã§ãæé»çã«Sendable
ã§ãã
泚èš: ããã«è©³çŽ°ã«ã€ããŠã¯ãThe Swift Programming Languageã®Sendable Typesã»ã¯ã·ã§ã³ãåç §ããŠãã ããã
Sendable
ãããã³ã«ã¯ãåå
šäœã®ã¹ã¬ããå®å
šæ§ãè¡šçŸããããã«äœ¿ãããŸããããããSendable
ã§ãªãåã®ããã€ã³ã¹ã¿ã³ã¹ãå®å
šãªæ¹æ³ã§äœ¿ãããŠããç¶æ³ããããŸããã³ã³ãã€ã©ã¯ãå€ãã®å ŽåããªãŒãžã§ã³ããŒã¹ã®éé¢ãšããŠç¥ããããããŒã»ã³ã·ãã£ããªè§£æã«ãã£ãŠãã®å®å
šæ§ãæšè«ã§ããŸãã
ãªãŒãžã§ã³ããŒã¹ã®éé¢ã§ã¯ãã³ã³ãã€ã©ãããŒã¿ç«¶åãåŒãèµ·ãããªãããšããããå ŽåãSendable
ã§ãªãåã®ã€ã³ã¹ã¿ã³ã¹ãéé¢ãã¡ã€ã³ãè¶
ããããšãèš±å¯ããŸãã
func populate(island: Island) async {
let chicken = Chicken()
await island.adopt(chicken)
}
ããã§ãã³ã³ãã€ã©ã¯ãããšãchicken
ãSendable
ã§ãªãåãä¿æããŠãããšããŠããisland
ã®éé¢ãã¡ã€ã³ã«æž¡ããŠãå®å
šã§ãããšæ£ããæšè«ã§ããŸãããããããã®Sendable
ãã§ãã¯ã®éåã¯ãæ¬è³ªçã«åšå²ã®ã³ãŒãã«äŸããŸããã³ã³ãã€ã©ã¯ãchicken
å€æ°ãžã®å®å
šã§ãªãã¢ã¯ã»ã¹ãçºçããå Žåããšã©ãŒãçºçãããŸãã
func populate(island: Island) async {
let chicken = Chicken()
await island.adopt(chicken)
// ãšã©ãŒã«ãªã
chicken.eat(food: Pineapple())
}
ãªãŒãžã§ã³ããŒã¹ã®éé¢ã¯ãã³ãŒããå€æŽããã«æ©èœããŸããäžæ¹ã§ããã®ä»çµã¿ã䜿ã£ãŠãé¢æ°ã®ãã©ã¡ãŒã¿ãšæ»ãå€ããéé¢ãã¡ã€ã³ãè¶ ããããšãæ瀺ã§ããŸãã
func populate(island: Island, with chicken: sending Chicken) async {
await island.adopt(chicken)
}
ããã«ãããã³ã³ãã€ã©ã¯ããã¹ãŠã®åŒã³åºãå
ã§chicken
ãã©ã¡ãŒã¿ãžã®å®å
šã§ãªãã¢ã¯ã»ã¹ãã§ããªãããšã100%ä¿èšŒã§ããŸããsending
ã¯ããã®ä»çµã¿ããªããã°çºçããŠããé倧ãªå¶çŽãç·©åããŸããã€ãŸããsending
ããªããã°ããã®é¢æ°ã¯ãChicken
ããŸãSendable
ã«æºæ ããªãã°å®è£
ã§ããªããšããããšã§ãã
ã¢ã¯ã¿ãŒã¯å€åã§ã¯ãããŸããããã ããã¢ã¯ã¿ãŒã¯èªèº«ã®éé¢ãã¡ã€ã³ã§ãã¹ãŠã®ç¶æ
ãä¿è·ãããããå¢çãè¶ããŠæž¡ããŠãæ¬è³ªçã«å®å
šã§ããããã«ãããã¢ã¯ã¿ãŒã®ããããã£èªäœãSendable
ã§ãªããŠãããã¹ãŠã®ã¢ã¯ã¿ãŒåã¯æé»çã«Sendable
ã«ãªããŸãã
actor Island {
var flock: [Chicken] // non-Sendable
var food: [Pineapple] // Sendable
}
ã°ããŒãã«ã¢ã¯ã¿ãŒéé¢åããåæ§ã®çç±ã§æé»çã«Sendable
ã«ãªããŸãããã©ã€ããŒããªå°çšã®éé¢ãã¡ã€ã³ã¯ãããŸãããããã®ç¶æ
ã¯ã¢ã¯ã¿ãŒã«ãã£ãŠä¿è·ãããŠããŸãã
@MainActor
class ChickenValley {
var flock: [Chicken] // non-Sendable
var food: [Pineapple] // Sendable
}
å€åãšã¯ç°ãªããåç
§åã¯æé»çã«Sendable
ã«ã¯ã§ããŸãããæ瀺çã«Sendable
ã«ã§ããŸãããããã«ã¯ããã€ãã®å¶çŽã䌎ããŸããã¯ã©ã¹ãSendable
ã«ããããã«ã¯ãå¯å€ç¶æ
ãå«ãŸããŠããŠã¯ãªãããäžå€ã®ããããã£ãSendable
ã§ããå¿
èŠããããŸããããã«ãã³ã³ãã€ã©ã¯final
ã¯ã©ã¹ã®å®è£
ã®ã¿ãæ€èšŒã§ããŸãã
final class Chicken: Sendable {
let name: String
}
OSåºæã®æ§æèŠçŽ ããC/C++/Objective-Cã§å®è£
ãããã¹ã¬ããã»ãŒããªåã䜿çšããå Žåãªã©ãã³ã³ãã€ã©ãæšè«ã§ããªãåæããªããã£ãã䜿çšããŠãSendable
ã®ã¹ã¬ããã»ãŒãèŠä»¶ãæºãããŸãããã®ãããªåã¯ãã³ã³ãã€ã©ã«ãã®åãã¹ã¬ããã»ãŒãã§ããããšãçŽæããããã«ã@unchecked Sendable
ã«æºæ ãããšã¢ã€ã³ã³ã§ããŸããã³ã³ãã€ã©ã¯@unchecked Sendable
åã«å¯ŸããŠãã§ãã¯ãè¡ãªããªãããããã®ãªããã¢ãŠãã®äœ¿çšã«ã¯æ³šæãå¿
èŠã§ãã
ãããã¡ã€ã³ã®é¢æ°ãå¥ã®ãã¡ã€ã³ã®é¢æ°ãåŒã³åºããšãã¿ã¹ã¯ã¯éé¢ãã¡ã€ã³ãåãæ¿ããããšãã§ããŸããéé¢å¢çãè¶ããåŒã³åºãã¯ãåŒã³åºãå ã®éé¢ãã¡ã€ã³ããä»ã®ã¿ã¹ã¯ã®å®è¡ã§ããžãŒç¶æ ã«ãªã£ãŠããå¯èœæ§ããããããéåæã§è¡ãªãå¿ èŠããããŸãããã®å Žåãã¿ã¹ã¯ã¯ãåŒã³åºãå ã®éé¢ãã¡ã€ã³ã䜿çšå¯èœã«ãªããŸã§äžæãããŸããéèŠãªã®ã¯ãäžæãã€ã³ãããããã¯ãããªãããšã§ããçŸåšã®éé¢ãã¡ã€ã³(ããã³ãããå®è¡ãããŠããã¹ã¬ãã)ã¯ãä»ã®äœæ¥ãããããã«è§£æŸãããŸããSwiftã®äžŠè¡åŠçã©ã³ã¿ã€ã ã¯ãã·ã¹ãã ãåžžã«åé²ã§ããããã«ãã³ãŒããå°æ¥ã®äœæ¥ã§ãããã¯ããªãããšãæåŸ ããŸããããã¯äžŠè¡ã³ãŒãã®ãããããã¯ã®äžè¬çãªåå ãåãé€ããŸãã
@MainActor
func stockUp() {
// MainActorã§å®è¡éå§
let food = Pineapple()
// islandã¢ã¯ã¿ãŒã®ãã¡ã€ã³ã«åãæ¿ã
await island.store(food)
}
æœåšçãªäžæãã€ã³ãã¯ããœãŒã¹ã³ãŒãå
ã§await
ããŒã¯ãŒãã䜿çšããŠã¢ã€ã³ã³ãããŸãããã®ããŒã¯ãŒããååšãããšãåŒã³åºããå®è¡æã«äžæãããå¯èœæ§ãããããšã瀺ããŸãããã ããawait
ã¯äžæã匷å¶ãããã®ã§ã¯ãªããåŒã³åºãããé¢æ°ã¯ãç¹å®ã®åçæ¡ä»¶äžã§ã®ã¿äžæãããå¯èœæ§ããããŸããawait
ã§ã¢ã€ã³ã³ãããåŒã³åºãã¯ãå®éã«ã¯äžæãããªãå¯èœæ§ããããŸãã
ã¢ã¯ã¿ãŒã¯ããŒã¿ç«¶åããã®å®å šæ§ãä¿èšŒããŸãããäžæãã€ã³ãéã®ã¢ãããã¯æ§ã¯ä¿èšŒããŸããã䞊è¡ã³ãŒãã¯ãäžé£ã®åŠçãã¢ãããã¯ãªåäœãšããŠãŸãšããŠå®è¡ããå¿ èŠããããŸãããã®æ§è³ªãå¿ èŠãšããã³ãŒãã®åäœã*ã¯ãªãã£ã«ã«ã»ã¯ã·ã§ã³(critical section)*ãšåŒã³ãŸãã
çŸåšã®éé¢ãã¡ã€ã³ã¯ãä»ã®äœæ¥ãããããã«è§£æŸããããããã¢ã¯ã¿ãŒã§éé¢ãããŠããç¶æ ã¯ãéåæåŒã³åºãã®åŸã«å€æŽãããå¯èœæ§ããããŸããçµæãšããŠãæœåšçãªäžæãã€ã³ããæ瀺çã«ã¢ã€ã³ã³ããããšã¯ãã¯ãªãã£ã«ã«ã»ã¯ã·ã§ã³ã®çµäºã瀺ãæ¹æ³ãšããŠèããããšãã§ããŸãã
func deposit(pineapples: [Pineapple], onto island: Island) async {
var food = await island.food
food += pineapples
await island.store(food)
}
ãã®ã³ãŒãã§ã¯ãisland
ã¢ã¯ã¿ãŒã®food
ã®å€ãéåæåŒã³åºãã®éã«å€åããªãããšãã誀ã£ãŠæ³å®ããŠããŸããã¯ãªãã£ã«ã«ã»ã¯ã·ã§ã³ã¯ãåžžã«åæçã«å®è¡ãããããã«æ§é åãããã¹ãã§ãã
泚èš: ããã«è©³çŽ°ã«ã€ããŠã¯ãThe Swift Programming Languageã®[Defining and Calling Asynchronous Functions][]ã»ã¯ã·ã§ã³ãåç §ããŠãã ããã