머리말
Swift는 다른 언어와 다르게 함수의 파라미터가 상수여서 파라미터의 값을 변경하려면 "inout"이라는 키워드를 사용해야 한다. 우리말로 하면 "출입"이라는 키워드일텐데 도대체 이 키워드는 무엇인지 살펴 보자.
본문
공식문서의 inout
한번 공식문서에서 inout을 살펴 보자
In-Out Parameters in Functions
You write an in-out parameter by placing the inout keyword right before a parameter’s type. An in-out parameter has a value that’s passed in to the function, is modified by the function, and is passed back out of the function to replace the original value. For a detailed discussion of the behavior of in-out parameters and associated compiler optimizations, see In-Out Parameters.
in-out 파라미터는 파라미터의 타입 바로 전에 inout 키워드를 작성한다. in-out 파라미터는 함수로 전달하는 값을 가지고 있고 함수로 부터 이 값을 수정하고 원래 값을 대체하기 위해 함수 밖으로 다시 되돌린다. In-out 파라미터와 컴파일러 최적화의 동작에 대한 자세한 설명은 In-Out 파라미터 (In-Out Parameters)를 참고.
In-Out Parameters - Functions | Swift Documentation
코드 예시
두 정수를 교환하는 함수
아래 코드를 확인해 보자.
inout 키워드를 파라미터로 사용하고, 앰퍼샌드라 불리는 `&` 기호를 아규먼트에 사용하여 할당한 두 변수의 값을 바꾸는(재할당하는) 함수이다.
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
let temp = a
a = b
b = temp
}
var someInt = 92
var anotherInt = 30
swapTwoInts(&someInt, &anotherInt) // someInt = 30, anotherInt = 92
inout과 `&`가 없다면?
만약 inout과 `&`를 제외하고 코드를 작성하면 파라미터가 상수이기에 에러가 발생한다.
func swapTwoInts(_ a: Int, _ b: Int) {
let temp = a
a = b // 🔥 error: cannot assign to value: 'a' is a 'let' constant
b = temp // 🔥 error: cannot assign to value: 'b' is a 'let' constant
}
var someInt = 92
var anotherInt = 30
swapTwoInts(someInt, anotherInt)
inout의 과정
inout 파라미터의 과정을 살펴 보자
과정 (copy-in copy-out)
- 함수 호출 시 파라미터의 변수에 대한 복사가 이루어진다.
- 함수 스코프 안에서, 복사한 변수의 값을 수정한다.
- 함수가 반환(return) 될 때, 변화된 값을 원본의 변수에 재할당한다.
이러한 과정을 copy-in copy-out라 부르는데 이를 줄여 Swif에서는 "inout"이라는 키워드로 이를 사용한다.
변수 앞에 붙는 주소 연산자, 앰퍼샌드(&)
in-out 파라미터로 변수만 전달할 수 있다. 상수와 리터럴은 수정할 수 없기 때문에 인수로 상수 또는 반복 값은 전달할 수 없다. 함수에 수정 가능함을 알리기 위해 in-out 파라미터에 인수로 전달할 때 변수의 이름 앞에 주소 연산자인 ampersand(앰퍼샌드; &)를 붙인다.
주소 연산자는 `&`를 실제 할당할 변수 앞에 써서 그 변수의 시작 주소를 할당하기 위해 쓴다. C언어의 포인터 개념에서 등장하면 쉽게 접할 수 있다.
'iOS > Swift' 카테고리의 다른 글
Swift에서타입에 상관없이 코드를 작성할 수 없을까? (feat. Swift Generics) (0) | 2024.01.02 |
---|---|
Swift) 프로토콜과 의존성 주입, 의존성 분리 원칙 (feat. DI & DIP) (1) | 2023.12.12 |
Swift) static member cannot be used on instance of type 오류 (feat. 중첩한 타입) (1) | 2023.11.09 |
Swift) 클로저의 캡처와 참조 타입 (1) | 2023.08.31 |
[Swift] didSet과 값 타입, 참조 타입의 인스턴스 (1) | 2023.08.22 |
댓글