์ค์ํํธ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฝ๋์์ ๋ฐ์ํ ์ ์๋ unsafeํ ๋์๋ค์ ๋ฐฉ์ง ํ๋ค. ์๋ฅผ ๋ค์ด, ๋ณ์๊ฐ ์ด๊ธฐํ ๋์ด์ผ๋ง ์ฌ์ฉํ ์ ์๊ณ , ๋ฉ๋ชจ๋ฆฌ๊ฐ deallocated ๋๊ธฐ์ ์ ์ ๊ทผ์ด ์๋๊ณ , ๋ฐฐ์ด์์ indece๊ฐ out-of-bounds ์๋ฌ๊ฐ ๋๋์ง ์ฒดํฌํด์ค๋ค. ์ค์ํํธ๋ ์ฌ๋ฌ๊ฐ์ ์ ๊ทผ์ด ํ ๋ฉ๋ชจ๋ฆฌ ์ง์ญ์ ์ ๊ทผํ๋๋ผ๋ ์ฝ๋๊ฐ ๋ฉ๋ชจ๋ฆฌ์ ๋ฐฐํ์ ์ผ๋ก ์ ๊ทผํ๊ฒํจ์ผ๋ก์จ ๋ฉ๋ชจ๋ฆฌ ์ถฉ๋์ด ์ผ์ด๋์ง ์๋๋ก ํ๋ค. ์ค์ํํธ๋ ์๋์ ์ผ๋ก ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ๋ฅผ ํ๊ธฐ ๋๋ฌธ์ ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ๋ฉ๋ชจ๋ฆฌ์ ๋ํด ์ ๊ฒฝ ์ธ ํ์๊ฐ ์๋ค. ์ฝ๋ ๋ด์ ์ถฉ๋์ด ์๋ค๋ฉด, ์ปดํ์ผ ํ์์ด๋ ๋ฐํ์์ ์๋ฌ๋ฅผ ๋ฐ์ ์ ์๋ค.
๋ณ์์ ๊ฐ์ ์ง์ ํ๊ฑฐ๋ ํจ์์ ์ธ์๋ฅผ ๋๊ฒจ์ค ๋ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ์ด ์ผ์ด๋๋ค. ์๋ฅผ๋ค์ด, ๋ค์ ์ฝ๋์์๋ ์ฝ๊ธฐ, ์ฐ๊ธฐ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ์ด ์ผ์ด๋๋ค.
// A write access to the memory where one is stored.
var one = 1
// A read access from the memory where one is stored.
print("We're number \(one)!")
๋ค๋ฅธ ์ฝ๋์์ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ location์ ๋์์ ์ ๊ทผํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ์ถฉ๋์ด ์ผ์ด๋ ์ ์๋ค. ํ ๋ฉ๋ชจ๋ฆฌ location์ ์ฌ๋ฌ ์ ๊ทผ์ ํ๋ค๋ฉด ์์ํ ์ ์๋, ์ผ๊ด์ ์ด์ง ์์ ๋์์ด ์ผ์ด๋ ์ ์๋ค. ์ค์ํํธ์์๋, ํ๋์ ๊ฐ์ ๋ฐ๊พธ๊ธฐ ์ํด ์ฌ๋ฌ์ค์ ์ฝ๋๊ฐ ์คํ๋ ์ ์๋๋ฐ ์ด ์๊ฐ๋์ ๊ฐ์ ๊ฐ์ ์ ๊ทผํ๋ ค๋ ์๋๊ฐ ์์ ์ ์๋ค.
๊ฐ๊ณ๋ถ๋ก ๋น๋ ๋ฉ๋ชจ๋ฆฌ ์ถฉ๋ ์ค๋ช
- ๊ฐ๊ณ๋ถ ์์ ์ค์ Total์ ์ ๊ทผํ๋ค๋ฉด ์๊ธฐ์ ๋ฐ๋ผ์ ๋ค๋ฅธ ๊ฐ์ ์ป์ ์ ์๊ฒ ๋๋ ๋ฌธ์ ๊ฐ ์๋ค.
NOTE ๋ง์ฝ concurrent๋ multithreade code๋ฅผ ์์ฑํด ๋ณธ์ ์ด ์๋ค๋ฉด ์ด๋ฐ ๋ฉ๋ชจ๋ฆฌ ์ถฉ๋์ ์ต์ํ ๊ฒ์ด๋ค. ๊ทธ๋ฌ๋ ๋ฉ๋ชจ๋ฆฌ ์ถฉ๋์ด concurrent๋ multithreade ์ฝ๋๊ฐ ์๋๋๋ผ๋ single thread์์๋ ๋ฐ์ํ ์ ์๋ค. ๋ง์ฝ ์ฑ๊ธ ์ค๋ ๋์์ ๋ฉ๋ชจ๋ฆฌ ์ถฉ๋์ ๊ฒช๋๋ค๋ฉด, ์ค์ํํธ์์๋ ์ปดํ์ผ ํ์์ด๋ ๋ฐํ์์์ ์๋ฌ ๋ฉ์ธ์ง๋ฅผ ๋ฐ์๋ณผ ์์๋ค.(์๋ฌ๋ฉ์ธ์ง ์์ด ์๋ฌ๊ฐ ๋์ง๋ ์์ ๊ฑฐ๋ผ๋ ๋ป์ธ๋ฏ) multithreaded ์ฝ๋์์ "Thread Sanitizer๋ฅผ ์ฌ์ฉํ๋ฉด thread๋ฅผ ๋๋๋๋ ๋ฉ๋ชจ๋ฆฌ ์ถฉ๋์ ๊ฐ์งํ ์ ์๋ค."
๋ฉ๋ชจ๋ฆฌ ์ถฉ๋์ ์ดํดํ๊ธฐ ์ํด์๋ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ์ 3๊ฐ์ง ํน์ง์ ์ ํ์๊ฐ ์๋ค.
- ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ฝ๊ธฐ ์ ๊ทผ์ธ์ง ์ฐ๊ธฐ ์ ๊ทผ์ธ์ง
- ์ ๊ทผ ์๊ฐ
- ์ ๊ทผ๋๋ ๋ฉ๋ชจ๋ฆฌ location
ํนํ, ๋ค์ ์ํฉ์ ๋ชจ๋ ๋ง์กฑ์ํค๋ 2๊ฐ์ง ์ ๊ทผ์ด ์ผ์ด๋๋ค๋ฉด ๋ฉ๋ชจ๋ฆฌ ์ถฉ๋์ด ๋ฐ์ํ ์ ์๋ค.
-
์ฐ๊ธฐ ์ ๊ทผ์ด๊ฑฐ๋ nonatomic ์ ๊ทผ ์ค ํ๋๋ฅผ ๋ง์กฑ
-
์ ๊ทผ๋ค์ด ํ๊ฐ์ง ์ง์ญ์ ์ ๊ทผ
-
์ ๊ทผ ์๊ฐ์ด ์๋ก ๊ฒน์นจ
์ฝ๊ธฐ์ ์ฐ๊ธฐ ์ ๊ทผ์ ์ฐจ์ด๋ ๋ช ํํ๋ฐ ์ฐ๊ธฐ ์ ๊ทผ์ ํด๋น ๋ฉ๋ชจ๋ฆฌ ์ง์ญ์ ๋ฐ๊พผ๋ค.(์ฝ๊ธฐ ์ ๊ทผ์ ๋ฐ๊พธ์ง ์์) ๋ฉ๋ชจ๋ฆฌ ์ง์ญ(location in memory)๋ ๋ฌด์์ด ์ ๊ทผ๋ ์ง๋ฅผ ๋ปํ๋ค.(์๋ฅผ ๋ค์ด, ๋ณ์, ์์, property)
๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ์๊ฐ์ ์๊ฐ์ ์ด๊ฑฐ๋(instantaneous) long-term์ผ ์ ์๋ค.
์ํ ๋ฏน ์คํผ๋ ์ด์ ์ด๋ C ์ํ ๋ฏน ์คํผ๋ ์ด์ ์ ๋ปํ๋ค. C ์ํ ๋ฏน ์คํผ๋ ์ด์ ์ ๋ชฉ๋ก์ ๋ณด๊ณ ์ถ๋ค๋ฉด stdatomic(3) ๋ฉ๋ด์ผ ํ์ด์ง๋ฅผ ์ฐธ๊ณ
์ ๊ทผ์ด ์๊ฐ์ (instantaneous)ํ๋ค๋ ๊ฒ์ ํด๋น์ ๊ทผ ๋๋ ๋๊น์ง ๋ค๋ฅธ ์ฝ๋๊ฐ ์คํ๋์ง ์์์ ๋ปํ๋ค. ๋ฐ๋ผ์ 2๊ฐ์ ์๊ฐ์ (instantaneous)ํ ์ฝ๋๋ ๋์์ ์คํ๋ ์ ์๋ค. ๋๋ถ๋ถ์ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ์ ์๊ฐ์ (instantaneous)ํ๋ค. ์๋ฅผ๋ค์ด ์๋ ์ฝ๋์์์ ์ฝ๊ธฐ ์ ๊ทผ๊ณผ ์ฐ๊ธฐ ์ ๊ทผ์ ์ ๋ถ instantaneousํฉ๋๋ค.
func oneMore(than number: Int) -> Int {
return number + 1
}
var myNumber = 1
myNumber = oneMore(than: myNumber)
print(myNumber)
// Prints "2"
๋กฑํ ์ ๊ทผ์ ๋ค๋ฅธ ๋กฑํ ์ ๊ทผ๋ instantaneous์ ๊ทผ ์ฝ๋์ ์๊ฐ์ด ์ค์ฒฉ๋ ์ ์๋ค.
์ค์ฒฉ๋๋ ์ ๊ทผ์ด ์ฃผ๋ก ์ผ์ด๋๋ ์ฝ๋๋ "ํจ์๋ ๋ฉ์๋์์ in-out ํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ์ฉ"ํ๊ฑฐ๋ "์คํธ๋ญํธ์์ mutating ๋ฉ์๋"๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด๋ค.
์ด์ ํ๋์ฉ ์ดํด๋ณด์
ํจ์๋ ๋ชจ๋ in-out parameter์ ๋ํด ๋กฑํ write access ๋ฅผ ๊ฐ์ต๋๋ค.
in-out ํ๋ผ๋ฏธํฐ์ ๋ํ ์ฐ๊ธฐ ์ ๊ทผ์ ๋ชจ๋ non-in-outํ๋ผ๋ฏธํฐ๊ฐ evaluated ๋ ๋ค๋ถํฐ ํจ์์ ํธ์ถ์ด ๋๋ ๋๊น์ง ์ ์ง๋ฉ๋๋ค. ๋ง์ฝ์ ์ฌ๋ฌ๊ฐ์ in-out ํ๋ผ๋ฏธํฐ๊ฐ ์๋ค๋ฉด ํ๋ผ๋ฏธํฐ์ ์ฐ์ฌ์๋ ์์๋๋ก ์ฐ๊ธฐ ์ ๊ทผ์ด ์์๋ฉ๋๋ค.
๋กฑํ ์ฐ๊ธฐ ์ ๊ทผ์ผ๋ก ์ธํ ์ฐ๊ธฐ ์ in-outํ๋ผ๋ฏธํฐ๋ก ๋์ด์จ ๊ฐ์ ์ค๋ฆฌ์ง๋ ๊ฐ์ ์ ๊ทผํ ์ ์๋ค.
var stepSize = 1
func increment(_ number: inout Int) {
number += stepSize
}
increment(&stepSize)
// Error: conflicting accesses to stepSize
- ์ ์ฝ๋์์ ํจ์๋ก ๋์ด์จ inout parameter์ ๋ํด ์ฐ๊ธฐ ์ ๊ทผ์ด ์์๋๋๋ฐ ํจ์๋ด๋ถ์์ stepsize์ ๋ํ ์ฝ๊ธฐ ์ ๊ทผ์ด ์ผ์ด๋๋ฏ๋ก ๊ฐ ์ ๊ทผ์ด ์ค์ฒฉ๋๋ฏ๋ก ์ถฉ๋์ด ์ผ์ด๋ฉ๋๋ค.
์ด ์ถฉ๋์ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ stepSize๋ฅผ ๋ณต์ฌํด๋ฒ๋ฆฌ๋ฉด ๋ฉ๋๋ค.
// Make an explicit copy.
var copyOfStepSize = stepSize
increment(©OfStepSize)
// Update the original.
stepSize = copyOfStepSize
// stepSize is now 2
์ด๋ ๊ฒ ๋๋ฉด ์ฐ๊ธฐ์ ๊ทผ์ด ์์๋๊ธฐ ์ ์ ์ฝ๊ธฐ ์ ๊ทผ์ด ๋๋๊ธฐ ๋๋ฌธ์ ์ถฉ๋์ด ์ผ์ด๋์ง ์๋๋ค.
๋ค๋ฅธ ๋ฌธ์ ์ ์ผ๋ก๋ ์ฌ๋ฌ๊ฐ์ in-output ํ๋ผ๋ฏธํฐ๋ก ํ๋์ ๊ฐ์ ๋๊ธฐ๋ฉด ์ถฉ๋์ด ์๊ธธ ์ ์๋ค. For example:
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: conflicting accesses to playerOneScore
๋ค๋ฅธ ์ธ์ ๋ฉ๋ชจ๋ฆฌ ์์น์ ์ ๊ทผํ๋ ์ฒซ๋ฒ์งธ ๊ฒฝ์ฐ ์๊ฐ์ด ์ค์ฒฉ๋์ง๋ง ์ ๊ทผํ๋ ๋ฉ๋ชจ๋ฆฌ ์์น๊ฐ ๋ค๋ฅด๊ธฐ๋๋ฌธ์ ์ถฉ๋์ด ์ผ์ด๋์ง ์์ต๋๋ค. ์ด์ ๋ฌ๋ฆฌ, ๋๋ฒ์งธ ์์๋ ๊ฐ์ ๊ณณ์ ์ ๊ทผํ๊ธฐ๋๋ฌธ์ ์ถฉ๋์ด ์ผ์ด๋ฉ๋๋ค.
๊ตฌ์กฐ์ฒด์ ๋ฎคํ ์ดํ ๋ฉ์๋๋ ๋ฉ์๋๊ฐ ํธ์ถ๋ ์๊ฐ ๋์ self์ ๋ํด ์ฐ๊ธฐ ์ ๊ทผ์ ํ๊ฒ ๋ฉ๋๋ค.
struct Player {
var name: String
var health: Int
var energy: Int
static let maxHealth = 10
mutating func restoreHealth() {
health = Player.maxHealth
}
}
mutatin methos ์ธ restoreHealth()๋ ๋ฉ์๋๊ฐ ํธ์ถ๋ ์๊ฐ๋ถํฐ ๋ฆฌํด๋ ๋๊น์ง self์ ๋ํด ์ฐ๊ธฐ ์ ๊ทผ์ ํฉ๋๋ค. ์ด ๊ฒฝ์ฐ, ์ ๊ทผ์ ๋ํด ์ค์ฒฉ์ด ๋๋ ์ฝ๋๊ฐ ์๋ค.
ํ์ง๋ง, ์๋์ฒ๋ผ in-out ํ๋ผ๋ฏธํฐ๋ก ๋ค๋ฅธ 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๊ฐ maria์ ์ธ์คํด์ค๋ฅผ ํ๋ผ๋ฏธํฐ๋ก ๋ฐ๊ธฐ ๋๋ฌธ์ ์ถฉ๋์ด ์ผ์ด๋์ง ์์ต๋๋ค. ์ ํจ์๋ oscar์ ๋ํด ์ฐ๊ธฐ ์ ๊ทผ์ด ์ผ์ด๋๊ณ (mutating ๋ฉ์๋์ด๊ธฐ๋๋ฌธ์) in-out ํ๋ผ๋ฏธํฐ๋ก ๋ฐ์ maria์ ๋ํด์๋ ๋์ผํ ์๊ฐ๋์ ์ฐ๊ธฐ ์ ๊ทผ์ด ์ผ์ด๋๋ค. ํ์ง๋ง ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ค๋ฅธ ์ง์ญ์ ์ ๊ทผํ๊ธฐ ๋๋ฌธ์ ์ถฉ๋์ด ์ผ์ด๋์ง ์์ต๋๋ค.
๊ทธ๋ฌ๋ oscar.shareHealth๊ฐ oscar๋ฅผ in-out parameter๋ก ๋ฐ๋๋ค๋ฉด ์ถฉ๋์ด ์ผ์ด๋ ์ ์๋ค.
oscar.shareHealth(with: &oscar)
// Error: conflicting accesses to oscar
์ ์ฝ๋์์๋ ๊ฐ์ ๊ณณ์ ๊ฐ์ ์๊ฐ์ ์ ๊ทผํ๊ธฐ ๋๋ฌธ์ ์ถฉ๋์ด ์ผ์ด๋ ์ ์๋ค.
๊ตฌ์กฐ์ฒด์ ํ๋กํผํฐ๋ ํํ์ element๋ ๊ฐ ํ์ ์ด๊ธฐ๋๋ฌธ, ๋ถ๋ถ์ ์์ ํด๋ ์ ์ฒด๊ฐ ๋ค ์์ ๋๋ค. ์ด ๋ง์ ํ๋กํผํฐ๋ค ์ค ํ๋์ ๋ํ ์ฝ๊ธฐ ์ฐ๊ธฐ ์ ๊ทผ์ ์ ์ฒด ํ์ ์ ๋ํ ์ฝ๊ธฐ, ์ฐ๊ธฐ ์ ๊ทผ์ด๋ผ๊ณ ํ๋ค.
์๋ฅผ ๋ค์ด, ๋ค์๊ณผ ๊ฐ์ ์ฝ๋๋ ์ถฉ๋์ ์ผ์ผํจ๋ค.
var playerInformation = (health: 10, energy: 20)
balance(&playerInformation.health, &playerInformation.energy)
// Error: conflicting access to properties of playerInformation
์์ ์ผ์ด์ค์์ balance()์ in-out ํ๋ผ๋ฏธํฐ๋ก playInformation์ health์ energy๊ฐ ๋์ด์ค๋๋ฐ ๊ฐ๊ฐ ์ ์ฒด ํ์ ์ ์ฐ๊ธฐ ์ ๊ทผ์ด ์ผ์ด๋๋ค. health์ ์ํด์ ์ ๊ทผ๋ ๋ฉ๋ชจ๋ฆฌ์ energy์ ์ํด ์ ๊ทผ๋ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๊ฐ์๊ณณ์ด๊ณ , ๊ฐ์ ์๊ฐ์ด๊ธฐ ๋๋ฌธ์ ์ถฉ๋์ ์ผ์ผํจ๋ค.
์์ ๋น์ทํ ์๊ฐ ์ ์ญ๋ณ์๋ก ์ ์ธ๋ ๊ตฌ์กฐ์ฒด์ ํ๋กํผํฐ ์ ๊ทผ์์๋ ์ผ์ด๋ฉ๋๋ค.
var holly = Player(name: "Holly", health: 10, energy: 10)
balance(&holly.health, &holly.energy) // Error
์ฌ์ค ๊ตฌ์กฐ์ฒด ํ๋กํฐํผ์ ๋ํ ๋๋ถ๋ถ์ ์ ๊ทผ์ด ์์ ํ๊ฒ ์ค์ฒฉ๋๋ค.(์ถฉ๋์ด ์ผ์ด๋์ง ์๋๋ค.)
์๋ฅผ๋ค์ด, ์๋์ ์์ ๊ฐ์ด ํ์ ์ ๊ธ๋ก๋ฒ ๋ณ์๋ก ์ ์ธํ์ง ์๊ณ ๋ก์ปฌ ๋ณ์๋ก ์ ์ธํ๋ค๋ฉด ๊ตฌ์กฐ์ฒด์ ์ ์ฅ ํ๋กํผํฐ์ ์ค์ฒฉ๋ ์ ๊ทผ์ ํ๋๋ผ๋ ์ปดํ์ผ๋ฌ๊ฐ ์์ ํ๋ค๊ณ ์ฌ๊ธธ ์ ์๊ฒ ๋๋ค.
func someFunction() {
var oscar = Player(name: "Oscar", health: 10, energy: 10)
balance(&oscar.health, &oscar.energy) // OK
}
์ปดํ์ผ๋ฌ๊ฐ ์์ ๊ฐ์ ์ํฉ์ ๋ฉ๋ชจ๋ฆฌ ์ธ์ดํํฐํ๋ค๊ณ ๋ณด์ฅํด์ฃผ๊ฒ ๋๋ค. ์๋ํ๋ฉด ๋๊ฐ์ ์ ์ฅํ๋กํผํฐ๊ฐ ์ด๋ค์์ผ๋ก๋ ์๋ก ์ฐ๊ด์ด ์๊ธฐ ๋๋ฌธ์ด๋ค.
๊ตฌ์กฐ์ฒด์ ํ๋กํผํฐ์ ๋ํ ์ค์ฒฉ ์ ๊ทผ์ ์ ํํ๋ค๊ณ ํด์ ํญ์ ๋ฉ๋ชจ๋ฆฌ ์ธ์ดํํฐํ ๊ฒ์ ์๋๋ค. ๋ฉ๋ชจ๋ฆฌ ์ธ์ดํํฐ ์ด์์ผ๋ก ํด๋น ๋ฉ๋ชจ๋ฆฌ์ ๋ํ ์ ๊ทผ์ด ๋ฐฐํ์ ์ด์ด์ผ ํ๋ค. ์ด ๋ง์ ์ด๋ ํ ์ ๊ทผ์ด ๋ฉ๋ชจ๋ฆฌ ์ธ์ดํํฐ ํ์ง๋ง ๋ฉ๋ชจ๋ฆฌ์ ๋ฐฐํ์ ์ผ๋ก ์ ๊ทผํ์ง ์์ ์ ์๋ค๋ ๋ง์ด๋ค. ์ค์ํํธ๋ ์์ ๊ฐ์ ๋ฐฐํ์ ์ด์ง ์์ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ์ ๋ฉ๋ชจ๋ฆฌ ์ธ์ดํํฐํ๋ค๊ณ ๋ณด์ฅํด์ค ์ ์๋ค. ์ค์ํํธ๊ฐ ๊ตฌ์กฐ์ฒด ํ๋กํผํฐ์ ๋ํ ์ค์ฒฉ ์ ๊ทผ์ ๋ฉ๋ชจ๋ฆฌ ์ธ์ดํํ๊ฒ์ผ๋ก ํ์ ํด ์ฃผ๊ธฐ ์ํด์๋ ๋ค์๊ณผ ๊ฐ์ ์กฐ๊ฑด์ด ํ์ํ๋ค.
-
์ค์ง ์ธ์คํด์ค์ ์ ์ฅ ํ๋กํผํฐ์๋ง ์ ๊ทผํด์ผ ํ๋ค. ๊ณ์ฐ ํ๋กํผํฐ๋ ํด๋์ค ํ๋กํผํฐ๋ ์๋๋ค.
-
๊ตฌ์กฐ์ฒด๋ ๋ก์ปฌ ๋ณ์๋ก ์ ์ธ๋์ด์ผ ํ๋ค. ์ ์ญ ๋ณ์๋ก ์ ์ธ๋๋ฉด ์๋๋ค.
-
๊ตฌ์กฐ์ฒด๋ ํด๋ก์ ์ ์ํด ์บก์ฒ๋๊ฑฐ๋ ์บก์ฒ๋๋๋ผ๋ nonescaping ํด๋ก์ ์ ์ํด์ ์บก์ฒ๋์ด์ผ ํ๋ค.
๋ง์ฝ ์์ ๊ฐ์ ์กฐ๊ฑด์ด ์ฑ๋ฆฝ๋์ง ์์ผ๋ฉด ์ ๊ทผ์ ํ์ฉํ์ง ๋ชปํ๋ค.