함수 파라미터는 기본적으로 상수이다.
함수 본문 내에서 파라미터 값을 변경하려고 하면 에러 발생
따라서 함수 파라미터 값을 변경하고, 함수 호출이 종료된 후에도 그 값을 유지하고 싶다면 inout 파라미터를 사용해 보자.
inout
키워드를 작성해 준다.&
붙여주기func swapTwoInts(_ a: inout Int, _ b: inout Int) {
let tmpA = a
a = b
b = tmpA
}
var a = 5
var b = 3
swapTwoInts(&a, &b)
print(a, b) // 3 5
참고로 Swift에는 swap 함수가 이미 내장되어 있긴 하다
사실 call by value라는 의미다.
(copy-in copy-out이라고도 할 수 있다.
함수에 전달된 인수의 값을 복사하고 copy-in,
함수가 반환될 때 변경된 값을 원래 변수에 다시 복사하여 반영 copy-out)
var number: Int = 2 {
willSet { // 새 값이 저장되기 직전 호출
print("newValue:", newValue)
}
didSet { // 새 값이 저장된 직후 호출
print("oldValue:", oldValue)
}
}
func inoutTest(num: inout Int) {
print("inoutTest1:", number)
num = 5
print("inoutTest2:", number)
num = 7
print("inoutTest3:", number)
}
inoutTest(num: &number)
print("number:", number) // 7
/*
inoutTest1: 2
inoutTest2: 2
inoutTest3: 2
newValue: 7
oldValue: 2
number: 7
*/
해당 코드를 보면, number
출력은 항상 2로 동일함을 알 수 있고,
함수 종료 후 number
출력 시엔 값이 변경된다.
하지만 실제 메모리 주소에 저장된 값이 inout
파라미터로 전달될 경우, 컴파일러는 최적화를 적용할 수 있다.
call by reference와 동일한 원리로 메모리 위치가 함수 본문 내부와 외부에서 사용되어 copy-in copy-out과 같은 효과를 낼 수 있지만 오버헤드는 줄일 수 있다는 것.
하지만 우리가 코드를 작성할 때는 이러한 최적화에 의존하지 않고 또는 신경쓰지 않고,
copy-in copy-out으로 작성하여 최적화를 하지 않고도 잘 동작하도록 해야 한다.
최적화는 컴파일러의 몫……………………………..
.
.
.
아무리 해석해 보고 이해해 보고 찾아봐도 이렇게밖에 이해가 안 된다…
도와주십시오…
in-out 파라미터는 기본값을 가질 수 없고, 가변 파라미터는 inout
으로 표기할 수 없음
inout 인수로 전달된 값은 접근할 수 없다
var property = 3
func inoutTest(_ p: inout Int) {
p += property
}
// 🚨 error
inoutTest(&property)
여러 개의 inout 파라미터에 동일한 값을 전달할 수 없다
in-out 파라미터를 캡처하는 클로저 또는 중첩 함수는 non-escaping이어야 함
캡처리스트를 사용하여 inout 파라미터가 변경되지 않게 할 수 있다.
func someFunction(a: inout Int) -> () -> Int {
return { [a] in return a + 1 }
}