Swift

[Swift] inout

yujaehui 2024. 4. 8. 10:53

1. inout 파라미터란?

Swift는 기본적으로 함수의 파라미터를 값 타입으로 취급.

즉, 함수 내부에서 파라미터의 값을 변경하더라도 함수 외부의 원본 값에는 영향을 미치지 않음.

 

하지만 특정 상황에서는 함수 내부에서 값을 변경하고, 그 변경된 값을 함수 호출부에 전달해야 할 때가 있음.

이때 inout 키워드를 사용하면 파라미터의 값을 함수 외부로 전달이 가능.


2. inout 파라미터의 동작 원리

inout 키워드는 함수를 호출할 때, 파라미터의 값을 복사하고 함수 내부에서 해당 복사본을 수정한 후, 수정된 값을 다시 원본으로 복사하는 방식으로 동작.

즉, inout은 직접 참조를 전달하는 것처럼 보이지만, 실제로는 복사-수정-반복사라는 메커니즘을 사용.


3. 문법

inout 파라미터를 선언하려면 함수의 파라미터 타입 앞에 inout 키워드를 붙임.

func swapValues(_ a: inout Int, _ b: inout Int) {
    let temp = a
    a = b
    b = temp
}

 

함수를 호출할 때는 &를 사용해 변수의 참조를 전달.

var x = 10
var y = 20

swapValues(&x, &y)

print(x) // 20
print(y) // 10

4. 사용 예제

1. 값 교환(swap)

inout은 주로 값 교환처럼 함수 내부에서 값을 변경해야 하는 로직에 유용.

func swapStrings(_ first: inout String, _ second: inout String) {
    let temp = first
    first = second
    second = temp
}

var str1 = "Hello"
var str2 = "World"

swapStrings(&str1, &str2)

print(str1) // "World"
print(str2) // "Hello"

 

2. 배열의 요소 변경

배열의 특정 요소를 수정할 때도 inout을 사용할 수 있음.

func modifyArray(_ array: inout [Int], index: Int, newValue: Int) {
    if index >= 0 && index < array.count {
        array[index] = newValue
    }
}

var numbers = [1, 2, 3, 4, 5]

modifyArray(&numbers, index: 2, newValue: 10)

print(numbers) // [1, 2, 10, 4, 5]

5. 주의 사항

1. 상수 변수 전달 불가

inout 파라미터는 변경 가능한 변수에만 전달할 수 있으며, 상수나 리터럴은 사용할 수 없음.

let constantValue = 10
// swapValues(&constantValue, &y) // 오류 발생

 

2. 직접 참조처럼 보이지만, 복사본 사용

inout은 내부적으로 복사와 재복사를 사용하므로, 포인터를 직접 사용하는 언어(C, C++)와는 다름.

따라서 예상치 못한 성능 문제가 발생할 수 있기에, 성능이 중요한 경우 다른 접근법을 고려하는 것이 좋음.

 

3. 함수 체인에서의 제한

inout 파라미터는 함수 체인 내에서 사용할 수 없음.

var value = 5
// doubleValue(&value).description // 오류 발생

6. 언제 inout을 사용해야 할까?

  • 함수 내부에서 변수의 값을 변경해야 하는 경우.
  • 여러 개의 값을 반환하지 않고, 함수 호출자에게 값을 전달해야 하는 경우.
  • 값 타입(예: struct 또는 enum)의 데이터를 효율적으로 조작해야 할 때.

7. 결론

Swift의 inout 키워드는 값 타입을 함수 내부에서 수정하고, 변경된 값을 함수 외부에 전달할 때 유용.

하지만 사용 시 주의할 점도 많으므로, 불필요한 경우에는 구조체의 mutating 메서드나 클래스를 활용하는 것이 더 적합할 수 있음.

'Swift' 카테고리의 다른 글

[Swift] ARC  (0) 2024.04.13
[Swift] mutating  (0) 2024.04.12
[Swift] Escaping Closure (@escaping)  (0) 2024.04.05
[Swift] Value and Reference Types  (0) 2024.04.04
[Swift] Performance Optimization Tips  (0) 2024.04.04