홍로그

inout / mutating 본문

iOS

inout / mutating

성홍민 2023. 5. 26. 10:32

함수의 파라미터 값을 함수 내에서 변경할 수 없다.

이유: 값 타입의 불변성과 복사 전달

Swift에서 함수의 파라미터 값을 함수 내에서 변경할 수 없는 이유는 크게 두 가지 원인이 있다. 첫 번째는 값 타입의 불변성(Immutability)이고, 두 번째는 파라미터의 복사 전달(Copy-by-Value)이다.

1. 값 타입의 불변성

Swift에서 구조체(Struct)와 열거형(Enum)은 값 타입이다. 값 타입은 전달될 때마다 복사되어 독립적인 인스턴스를 생성하게 되며, 해당 인스턴스의 값을 변경할 수 없도록 설계되어 있다. 이는 값 타입이 예측 가능하고 안전한 동작을 보장하기 위한 중요한 특성이다. 따라서 함수 내에서 값 타입의 속성을 직접 변경하는 것은 원본 값을 변경하는 것이 아니라 복사본을 변경하는 것이기 때문에 호출자의 값에 영향을 주지 않는다.

2. 복사 전달

Swift에서 함수의 파라미터는 복사 전달 방식을 사용한다. 이는 호출자로부터 함수로 전달되는 값을 복사하여 함수 내에서 사용한다는 의미. 따라서 함수 내에서 파라미터 값을 변경하더라도 실제로는 복사된 지역 변수를 변경하는 것이므로 호출자의 변수에는 영향을 주지 않는다.

해결책: inout 매개변수와 반환값 활용 

값을 변경하기 위해서는 다음 두 가지 해결책을 사용할 수 있다.

1. inout 매개변수

inout 매개변수를 사용하여 함수 내에서 파라미터 값을 변경할 수 있다. inout 키워드를 매개변수 앞에 붙이고, 함수 내에서 해당 매개변수를 수정하면 호출자의 변수도 함께 변경된다. inout 매개변수는 변수에 대해서만 사용할 수 있으며, 함수 호출 시에 매개변수 앞에 &를 붙여 참조로 전달해야 한다.

func increment(_ number: inout Int) {
    number += 1
}

var x = 5
increment(&x)
print(x) // 출력: 6

2. 반환값 활용

함수가 값을 반환하고, 호출자가 반환값을 변수에 할당하는 방식으로 값을 변경할 수 있습니다. 함수 내에서 원하는 값을 계산하고, 그 값을 반환하여 호출자가 직접 변수에 할당하는 형태

func increment(_ number: Int) -> Int {
    return number + 1
}

var x = 5
x = increment(x)
print(x) // 출력: 6

그리고 mutating

mutating은 메서드 선언 시에 사용되며, 구조체의 메서드에서 속성 값을 변경하거나, 배열의 요소를 추가 또는 제거하는 등의 작업을 수행할 때 mutating 키워드가 필요하다.

struct Point {
    var x: Int
    var y: Int
    
    mutating func moveBy(x deltaX: Int, y deltaY: Int) {
        x += deltaX
        y += deltaY
    }
}

var point = Point(x: 10, y: 20)
print("이동 전 좌표: (\(point.x), \(point.y))") // 출력: 이동 전 좌표: (10, 20)

point.moveBy(x: 5, y: -3)
print("이동 후 좌표: (\(point.x), \(point.y))") // 출력: 이동 후 좌표: (15, 17)

inout과 mutating의 차이

  1. inout은 함수의 매개변수로 사용되고, 해당 함수 내에서 전달된 값을 변경한다. mutating은 구조체나 열거형 내의 메서드에서 사용되고, 해당 인스턴스의 속성 값을 변경한다.
  2. inout은 함수 호출 시에 매개변수에 &를 붙여 참조로 전달하며, 호출자의 변수를 변경할 수 있다. mutating은 구조체나 열거형의 인스턴스 내에서 호출되어 인스턴스의 속성을 변경할 수 있다.
  3. inout은 변수에 대해서만 사용할 수 있고, 상수에는 사용할 수 없다. mutating은 구조체나 열거형을 변경하는 메서드에서 사용된다.
반응형

'iOS' 카테고리의 다른 글

Swift Async/Await  (0) 2023.05.28
Swift Combine  (0) 2023.05.27
Swift final을 쓰는 이유  (0) 2022.11.01
UIWebView, WKWebView, SFSafariView 차이  (2) 2022.10.25
메모리 순환 참조 방식 ( Strong, Weak, Unowned )  (2) 2021.04.18