In-Out은 왜 사용하는 것일까?
C, C++, Python, Java 등의 언어에서 함수의 파라미터는 "변수"로 사용됩니다. 그렇다면, Swift에서도 함수의 파라미터는 변수일까요?
답은 그렇지 않습니다. Swift에서 함수의 매개변수는 기본적으로 변경할 수 없는 값(상수처럼 동작)으로 처리됩니다.
즉, 함수 내에서 매개변수의 값을 직접 수정하려고 하면 컴파일 에러가 발생합니다.
그렇다면, 메서드 내에서 인자값을 변경하고 원본 변수에도 영향을 주어서 그 변수에서 벗어나더라도 값이 유지가 되게 하려면 어떻게 해야 할까요? 🤔
그럴 때 사용하는 것이 바로 inout 매개변수입니다.
보통 함수 내부에서 전달받은 값을 다른 변수에 저장해두고 처리하는 방식으로도 작업할 수 있지만, 이 경우 함수가 종료되면 값이 사라지고 외부 변수에는 영향을 주지 못합니다.
하지만 inout을 사용하면, 함수 내부에서의 변경 사항을 외부 변수에도 반영할 수 있게 됩니다.
In-Out 매개변수란?
inout 매개변수는 함수에 전달된 값을 함수 내부에서 변경하고, 그 변경 내용을 함수 외부의 원래 변수에도 반영하고자 할 때 사용됩니다.
그리고 in-out 매개변수로 전달할 경우에, 전달한 변수 앞에는 '&' 문자를 표시해주어야합니다. 그 이유는 "해당 변수가 in-out 매개변수로서 사용될 것이다."라는 것을 알려주기 위해서 표시해주는 것입니다.
사용방법은 아주 간단합니다.
- 함수 선언 시 해당 매개변수 앞에 inout 키워드를 붙인다.
- 함수를 호출할 때는 변수 앞에 & 기호를 붙여 사용한다.
자 이제 예시를 볼까요? 아래 코드는 Swift 언어 가이드에 있는 예시입니다. (링크는 아래 있습니다.)
func swapTwoInts(_ a: inout Int, _ b: inout Int) { // a = 2, b = 16
let temporaryA = a // temporaryA = 2
a = b // a = b(16)
b = temporaryA // b = a(2)
}
var firstInt = 2
var secondInt = 16
swapTwoInts(&firstInt, &secondInt)
print("firstInt is \(firstInt) and secondInt is \(secondInt)")
// "firstInt is 16 and secondInt is 2"
위 코드를 간단히 설명해보자면, in-out의 인자 값으로 사용할 "firstInt"와 "secondInt" 두 개의 변수명 앞에 '&'를 붙여서 swapTwoInts 메서드 a, b의 in-out 매개변수로 사용하였습니다.
swapTwoInts함수 안에서 firstInt의 값과 secondInt의 값을 스왑해주었으며, 위에서 설명한 대로 함수를 벗어나도 값을 유지시켜주기 위해서 in-out 매개변수를 사용했기 때문에 스왑 된 값은 함수를 벗어나도 값이 변경된 상태로 유지되는 것을 볼 수 있습니다.
In-Out의 동작 원리
Swift의 inout은 내부적으로 Copy-In Copy-Out 방식으로 동작합니다.
1. 함수를 호출할 때, 전달된 변수의 값이 복사되어 함수 내부로 전달됨 (Copy-In)
2. 함수 내부에서 복사된 값에 대한 연산이 수행됨
3. 함수가 종료되면, 변경된 값이 원래 변수로 다시 복사되어 저장됨 (Copy-Out)
마지막 정리
- Swift의 함수 매개변수는 기본적으로 불변이다.
- 함수 내부에서 전달된 값 자체를 변경하고, 변경된 값을 외부 변수에도 반영하고 싶을 때 inout 키워드를 사용한다.
- inout은 copy-in copy-out의 방식으로 동작한다.
- 함수를 호출할 때는 &를 붙여서 해당 변수가 inout 매개변수로 사용됨을 명시해주어야한다.
틀린 내용이나 오타는 댓글로 알려주시면 감사하겠습니다 :)
Reference
'📌 Swift' 카테고리의 다른 글
[오늘의 Swift 지식] 고차 함수 (map, filter, reduce) (0) | 2022.02.01 |
---|---|
[오늘의 Swift 지식] stride 함수 (백준 2742번 기찍 N, 역수 구하기) (0) | 2021.10.24 |
[오늘의 Swift 지식] 전달인자(Argument)와 매개변수(Parameter) (0) | 2021.08.13 |
[오늘의 Swift 지식] if let과 guard let의 차이는? (0) | 2021.08.09 |
[오늘의 Swift 지식] Optional Binding이란? 🧐 (0) | 2021.08.05 |