inout 파라미터
- Swift에서 함수의 매개변수(Parameter)는 기본적으로 값 전달(Call by Value) 방식이다
- 즉, 함수의 인자로 전달된 변수는 함수 내부에서 변경되더라도 원래 변수에는 영향을 미치지 않는다
- 하지만
inout 키워드를 사용하면 변수를 직접 수정할 수 있는 "참조 전달(Call by Reference)" 방식이 된다
- 즉, 함수 내부에서 변경된 값이 함수 외부에도 영향을 미치게 되는 것이다
기본적인 inout 파라미터 예제
1. inout 을 사용하지 않은 함수(값이 변경되지 않음)
func doubleValue(_ number: Int) {
var number = number
number *= 2
print("함수 내부 값: \(number)")
}
var myNumber = 10
doubleValue(myNumber)
print("함수 호출 후 값: \(myNumber)")
number 파라미터는 기본적으로 값 복사(Call by Value) 되므로, 함수 내부에서 값을 변경해도 원본 myNumber 에는 영향이 없음
2. inout 을 사용하여 원본 값 변경
func doubleValue(_ number: inout Int) {
number *= 2
}
var myNumber = 10
doubleValue(&myNumber)
print("함수 호출 후 값: \(myNumber)")
inout 을 사용하면 number 가 실제 변수에 대한 참조(Reference)로 전달
- 함수 내부에서
number 를 변경하면, 원래 변수인 myNumber 도 변경된다
&(앰퍼샌드) 기호를 사용하여 inout 파라미터를 전달해야 한다
inout 파라미터의 동작 방식
- 함수 호출 시 변수의 "주소(Reference)"가 전달된다
- 함수 내부에서 직접 원본 값을 수정할 수 있다
- 함수 실행이 끝나면 변경된 값이 원본 변수에 반영된다
inout 을 사용할 때는 반드시 & 를 붙여서 호출해야 한다
여러개의 inout 파라미터 사용
inout 파라미터는 여러 개 사용할 수도 있다
func swapValues(_ a: inout Int, _ b: inout Int) {
let temp = a
a = b
b = temp
}
var num1 = 5
var num2 = 10
print("교환 전: num1 = \(num1), num2 = \(num2)")
swapValues(&num1, &num2)
print("교환 후: num1 = \(num1), num2 = \(num2)")
교환 전: num1 = 5, num2 = 10
교환 후: num1 = 10, num2 = 5
swapValue(&num1, &num2) 호출 시 num1 과 num2 의 주소가 전달된다
a 와 b 를 바꾸면 원본 값도 변경된다
inout 파라미터의 제약
⚠️ inout 파라미터를 사용할 때 주의해야 할 점
1. 상수(Constant) 또는 리터럴을 직접 전달할 수 없다
func modifyValue(_ value: inout Int) {
value += 1
}
modifyValue(10)
해결 방법:
var number = 10
modifyValue(&number)
inout 은 변수의 주소를 전달해야 하므로, 반드시 변수(var)를 전달해야 한다
2. inout 파라미터는 기본값을 가질 수 없다
func updateNumber(_ value: inout Int = 5) {
value += 1
}
inout 은 참조(Reference) 방식이므로 기본값을 설정할 수 없다
3. inout 파라미터는 상수(let)에는 사용할 수 없다
let fixedNumber = 20
doubleValue(&fixedNumber)
inout 파라미터는 값이 변경되므로, 반드시 var 로 선언된 변수만 전달 가능하다
4. inout 파라미터는 클로저에서 캡처할 수 없다
func modifyValue(_ number: inout Int) {
let closure = {
number += 1
}
}
inout 파라미터는 함수 내부에서만 수정 가능하고, 클로저에서 캡처할 수 없다
inout vs return 을 이용한 값 변경
inout 파라미터 없이도 값을 반환하는 방식으로 원본 값을 변경할 수 있다
1. inout 을 사용한 방식
func squareInout(_ number: inout Int) {
number *= number
}
var value = 4
squareInout(&value)
print(value)
2. 반환값을 이용한 방식 (inout 없이 값 변경)
func square(_ number: Int) -> Int {
return number * number
}
var value = 4
value = square(value)
print(value)
- 새로운 값을 반환하여 변수에 다시 저장하는 방식
- 함수형 프로그래밍(Functional Programming)에서 선호된다
언제 inout 을 사용하고 언제 return 을 사용할까?
| 비교 항목 | inout 사용 | return 사용 |
|---|
| 코드 가독성 | 값이 직접 변경된다 | 새 값이 반환되므로 명확하다 |
| 변경 방식 | 원본 변수 변경 | 새 값을 대입해야 변경 |
| 사용 예시 | swap() 같은 직접 변경 함수 | square() 같은 연산 함수 |
| 함수형 프로그래밍 | ❌ 잘 사용되지 않음 | ✅ 선호된다 |
정리
| 개념 | 설명 |
|---|
inout | 함수 내부에서 매개변수를 직접 수정할 수 있도록 하는 키워드 |
| 값 전달(Call by Value) | 일반적인 함수 매개변수는 복사된다 (inout 사용 안함) |
| 참조 전달(Call by Reference) | inout 을 사용하면 원본 변수를 직접 수정 가능하다 |
| 사용 방법 | func myFunction(_ value: inout Int) |
| 호출 시 주의점 | & 기호를 붙여야 한다: myFunction(&myVar) |
| 제약 사항 | 리터럴, 상수(let), 기본값 사용 불가, 클로저에서 캡처 불가 |