Inout Parameter - ehrldyd15/Swift_Skills GitHub Wiki
Inout Parameter
inout Parameter
Swift์์ ํจ์์ ํ๋ผ๋ฉํฐ๋ ์์์ด๋ฏ๋ก ํจ์ ๋ด๋ถ์์ ํ๋ผ๋ฉํฐ์ ๊ฐ์ ๋ณ๊ฒฝํ ์ ์๋ค.
๋ง์ฝ ํจ์์์ ํ๋ผ๋ฉํฐ์ ๊ฐ์ ๋ณ๊ฒฝํ๊ณ , ๋ณ๊ฒฝ๋ ๊ฐ์ด ํจ์ ํธ์ถ์ด ์ข ๋ฃ๋ ํ์๋ ์ง์๋๊ธธ ์ํ๋ค๋ฉด
inout ํ๋ผ๋ฉํฐ๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
inout ํ๋ผ๋ฉํฐ๋ ํจ์ ์ ์์ ํ๋ผ๋ฉํฐ์ ํ์ ์ ์ inout ํค์๋๋ฅผ ์ถ๊ฐํ๋ฉด ๋๋ค.
inout ํ๋ผ๋ฉํฐ๋ ๋ณ์๋ง์ ์ทจ๊ธํ๋ฉฐ ํจ์์ ์ธ์๋ก ์ ๋ฌํ ๋ &๋ฅผ ์ฌ์ฉํ์ฌ ํด๋น ๊ฐ์ด ํจ์๋ด๋ถ์์ ๋ณ๊ฒฝ๋ ๊ฒ์์ ๋ํ๋ด์ผ ํ๋ค.
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
let temp = a
a = b
b = temp
}
var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
print("someInt: ", someInt) // 107
print("anotherInt: ", anotherInt) // 3
inout์ ์๋ฆฌ
inout ๋งค๊ฐ๋ณ์๋ ๋ค์์ ๊ณผ์ ์ ๊ฑฐ์น๋ค.
-
ํจ์๊ฐ ํธ์ถ๋๋ฉด, ๋งค๊ฐ๋ณ์๋ก ๋๊ฒจ์ง ๋ณ์๊ฐ ๋ณต์ฌ๋๋ค.
-
ํจ์ ๋ชธ์ฒด์์, ๋ณต์ฌํ ๊ฐ์ ์์ ํ๋ค.
-
ํจ์๊ฐ ๋ฐํ๋ ๋, ๋ณํ๋ ๊ฐ์ ์๋ณธ ๋ณ์์ ์ฌํ ๋นํ๋ค.
์ด ๋์์ copy-in copy-out ํน์ call by value result ๋ผ๊ณ ๋ถ๋ฅด๋ฉฐ inout์ ์ค์ ๋ก copy-in copy-out์ ์ค์๋ง์ด๋ค.
in-out ์ต์ ํ
Swift๋ inoutํ๋ผ๋ฉํฐ์ ๋ํ ์ต์ ํ๋ฅผ ์ํด ๊ฐ์ ๋ณต์ฌํ๋ ๊ฒ์ด ์๋๋ผ ๊ฐ์ด ์ ์ฅ๋ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๊ฐ์ ํจ์ ๋ด, ์ธ๋ถ์์ ์ฌ์ฉํ๋ค.
์ด ์ต์ ๊ธฐํ๋ฅผ call by reference๋ผ๊ณ ๋ถ๋ฅธ๋ค. ์ด๋ฅผ ํตํด ๋ณต์ฌ๋ก ์ธํ ์ค๋ฒํค๋๋ฅผ ์ค์ผ ์ ์๋ค.
inout์ ์ฌ์ฉํ ๋ ๊ฐ๋ฐ์๊ฐ ๋ฐ๋ก ์ต์ ํ๋ฅผ ๊ณ ๋ คํ ํ์๋ ์๋ค.
๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ
inout์ ์ฌ์ฉํ ๋๋ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ์ ์ฃผ์ํด์ผ ํ๋ค.
์๋์ ๊ฐ์ ์ํฉ์์ stepSize์ number๋ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ์ฐธ์กฐํ๊ธฐ ๋๋ฌธ์ ์ฝ๊ธฐ, ์ฐ๊ธฐ๊ฐ ๋์์ ์ด๋ฃจ์ด์ ธ ์ถฉ๋์ด ๋ฐ์ํ ์ ์๋ค.
var stepSize = 1
func increment(_ number: inout Int) {
number += stepSize
}
increment(&stepSize)
โ // Error: conflicting accesses to stepSize
inout ํ๋ผ๋ฉํฐ๋ฅผ ์บก์ณํ ์ ์๋ ํด๋ก์ , ์ค์ฒฉ ํจ์๋ ๋ฐ๋์ nonescaping์ด์ฌ์ผ ํ๋ค.
inout ํ๋ผ๋ฉํฐ๋ฅผ ์บก์ณํ๊ธธ ์ํ๋ค๋ฉด, ๋ฐ๋์ ์บก์ณ๋ฆฌ์คํธ๋ฅผ ์ฌ์ฉํด์ ํด๋น ํ๋ผ๋ฏธํฐ๋ฅผ ๋ถ๋ณ๊ฐ์ผ๋ก ๋ช ์ํด์ผํ๋ค.
func someFunction(a: inout Int) -> () -> Int {
return { [a] in return a + 1 }
}
๋ง์ฝ ๊ฐ์ ์บก์ณํ๊ณ , ๋ณ๊ฒฝ์ํค๊ธธ ์ํ๋ค๋ฉด local copy๋ฅผ ์ฌ์ฉํ์ฌ copy-in copy-out์ ์ง์ ๊ตฌํํด์ผํ๋ค.
๋ฉํฐ ์ค๋ ๋ ์ฝ๋์์ ๋ชจ๋ ๋ณ๊ฒฝ์ด ํจ์ ๋ฐํ ์ ์ ๋๋์ผํจ์ ๋ณด์ฅํ๋ ๊ฒฝ์ฐ๋ฅผ ์๋ก ๋ค ์ ์๋ค.
func multithreadedFunction(queue: DispatchQueue, x: inout Int) {
// Make a local copy and manually copy it back.
var localX = x
defer { x = localX }
// Operate on localX asynchronously, then wait before returning.
queue.async { someMutatingOperation(&localX) }
queue.sync {}
}