var one = 1 // ์ฐ๊ธฐ ์ ๊ทผ.
print("We're number \(one)!") // ์ฝ๊ธฐ ์ ๊ทผ.
์์) ์๋์์ ์ค๊ฐ ์ํ๋, ์๋ก ๋ฐ์๋ ๋ฌผํ์ ๊ฐ๊ฒฉ์ด total ์ ์ ์ฉ๋์ง ์์ ์ํ์ด๋ค. ์ฌ๊ธฐ์ total ์ ์ ๊ทผํ๊ฒ ๋๋ฉด ์๋ชป๋ ๊ฐ์ด ๋์จ๋ค.
NOTE : ๋์ / ๋ค์ค ์ฐ๋ ๋ ์ฝ๋๋ฅผ ์์ฑํ ๊ฒฝ์ฐ ๋ฉ๋ชจ๋ฆฌ ์ถฉ๋์ด ๋น๋ฒํ๊ฒ ๋ฐ์ํ๋ค. ํ์ง๋ง ์์๋ ๋จ์ผ ์ฐ๋ ๋์์ ์ถฉ๋์ด ๋ฐ์ํ๋ ๊ฒฝ์ฐ์ด๋ค.
๋จ์ผ ์ฐ๋ ๋ ๋ด ์ถฉ๋์ ์ปดํ์ผ / ๋ฐํ์ ์๋ฌ๋ฅผ ์ผ์ผํค๊ฒ ๋๊ณ ,
๋ค์ค ์ฐ๋ ๋ ์ฝ๋๋ Thread Sanitizer ๋ฅผ ์ฌ์ฉํด์ ์ฐ๋ ๋ ๊ฐ ์ถฉ๋์ ์ผ์ผํค๋ ์ ๊ทผ์ ๊ฐ์งํ ์ ์๋ค.
์๋ 3๊ฐ์ง ์กฐ๊ฑด์ ๋ชจ๋ ๋ง์กฑํ๋ 2๊ฐ์ ์ ๊ทผ์ด ์๋ค๋ฉด ์ถฉ๋์ด ๋ฐ์ํ๋ค.
๊ทธ๋ฐ๋ฐ... ๋ค๋ฅธ ์ฝ๋์ ์คํ์ ๊ฑธ์น ๊ฒฝ์ฐ, ๋ฉ๋ชจ๋ฆฌ์ ์ฅ๊ธฐ ์ ๊ทผ์ ํ๊ฒ ๋๋ค๋ฉด...
๋ฌธ์ 1 : ์ ๋ฌ๋ ์๋ ๋ณ์์ ์ ๊ทผํ ์ ์๋ค.
var stepSize = 1
func increment(_ number: inout Int) {
number += stepSize // stepSize ๋ฅผ ์ ๋ฌํ๋๋ฐ ์์์ stepSize ์ ์ ๊ทผ -> ์ค๋ฒ๋ฉ ์ถฉ๋.
}
increment(&stepSize)
// Error: conflicting accesses to stepSize
ํด๊ฒฐ1 : setpSize ์ ๋ณต์ฌ๋ณธ์ ์ง์ ํด์ inout ํ๋ผ๋ฏธํฐ๋ก ๋ณด๋ธ๋ค.
// Make an explicit copy.
var copyOfStepSize = stepSize
increment(©OfStepSize) // ๋ณต์ฌ๋ณธ์ ํจ์์ ์ธ์๋ก ๋ณด๋.
// Update the original.
stepSize = copyOfStepSize
// stepSize is now 2
// ์ฝ๊ธฐ ์ ๊ทผ์ด ์ฐ๊ธฐ ์ ๊ทผ์ด ์์๋๊ธฐ ์ ์ ๋๋จ
๋ฌธ์ 2 : inout ํ๋ผ๋ฏธํฐ์ ๋จ์ผ ๋ณ์๋ฅผ ๋๊ธฐ๋ฉด ์ถฉ๋์ด ๋ฐ์ํ๋ค.
func balance(_ x: inout Int, _ y: inout Int) {
let sum = x + y
x = sum / 2
y = sum - x
}
var playerOneScore = 42
var playerTwoScore = 30
balance(&playerOneScore, &playerTwoScore) // OK : ๋ ์ฐ๊ธฐ ์ ๊ทผ์ด ์ค๋ฒ๋ฉ ๋์ง๋ง ๋ค๋ฅธ ์ฃผ์์ ์ ๊ทผํ๋ ๊ฒ์ด๋ฏ๋ก ์๊ด ์์.
balance(&playerOneScore, &playerOneScore) // Error: ์ค๋ฒ๋ฉ ๋๋ฉฐ ๊ฐ์ ์ฃผ์์ ์ ๊ทผํจ -> conflict
struct Player {
var name: String
var health: Int
var energy: Int
static let maxHealth = 10
mutating func restoreHealth() {
health = Player.maxHealth
}
}
// sharedHealth ๋ผ๋ ํจ์๋ฅผ ๋ง๋ค๋ฉด, self (Player) ์ ๋ํ ์ค๋ณต ์ ๊ทผ ๊ฐ๋ฅ์ฑ์ด ์๊ธด๋ค.
extension Player {
mutating func shareHealth(with teammate: inout Player) {
balance(&teammate.health, &health)
}
}
var oscar = Player(name: "Oscar", health: 10, energy: 10)
var maria = Player(name: "Maria", health: 5, energy: 10)
oscar.shareHealth(with: &maria) // OK : ์ค๋ฒ๋ฉ์ ๋๋ ๋ค๋ฅธ ์ฃผ์์ ์ ๊ทผํ๊ณ ์์.
ํ์ง๋ง ๋ณธ์ธ๊ณผ ์ฒด๋ ฅ์ ๊ณต์ ํ๋ค๋ฉด..? ์ถฉ๋.
oscar.shareHealth(with: &oscar)
// Error: conflicting accesses to oscar
var playerInformation = (health: 10, energy: 20)
balance(&playerInformation.health, &playerInformation.energy)
// Error: conflicting access to properties of playerInformation ๊ฐ์ ํํ ์ธ์คํด์ค์ ๋ํ ์ฐ๊ธฐ ์ ๊ทผ์ ์๊ตฌํ๋ฉด์ ์ค๋ฒ๋ฉ ๋์ด ์ถฉ๋
var holly = Player(name: "Holly", health: 10, energy: 10)
balance(&holly.health, &holly.energy) // Error : ๊ฐ์ ๊ตฌ์กฐ์ฒด ์ธ์คํด์ค์ ๋ํ ์ฐ๊ธฐ ์ ๊ทผ ์ค๋ฒ๋ฉ -> ์ถฉ๋
// ๋ค๋ฅธ ๋ณ์๊ฐ holly ์ ์ ๊ทผํด์ ๋ญ๊ฐ๋ฅผ ๋ฐ๊พธ๋ ๋์ค์ balance ๊ฐ ์คํ๋ ์ ์๊ธฐ ๋๋ฌธ์ ์ถฉ๋.
ํด๊ฒฐ : holly ๊ฐ ์ ์ญ ๋ณ์๊ฐ ์๋๋ผ ์ง์ญ๋ณ์๋ผ๋ฉด ์ค๋ณต ์ ๊ทผ์ด ์์ ํ ์ ์์. 2๊ฐ์ ์ ์ฅ๋ ํ๋กํผํฐ๊ฐ ์ด๋ค์์ผ๋ก๋ ์ํธ์์ฉํ์ง ์๊ธฐ ๋๋ฌธ์ด๋ค. ๊ทผ๋ฐ... ์?
func someFunction() {
var oscar = Player(name: "Oscar", health: 10, energy: 10)
balance(&oscar.health, &oscar.energy) // OK : health ์ energy ๊ฐ ์ํธ์์ฉํ์ง ์์ ๊ฑฐ๋ผ๊ณ ๋ณด์ฅ์ด ๋จ by ์ปดํ์ผ๋ฌ -
// balance ๊ฐ ํ๋ฒ๋ง ์คํ๋๊ณ ์๊ณ , ์ง์ญ ๋ณ์๋ผ์ ํจ์ ๋ด๋ถ์์๋ง ์ฐ์ด๊ณ ์์ด์ง๊ธฐ ๋๋ฌธ.
// ๋ค๋ฅธ ๊ฒ์ด oscar ๋ณ์์ ์ ๊ทผํ ์ฐ๋ ค๊ฐ ์๋ค.
}
์ฐธ๊ณ