[Swift/iOS] In-Out Parameters From 공식문서
! 공식문서를 참고한 글입니다
In-Out Parameters
함수의 매개변수는 기본적으로 상수
실수로 파라미터의 값을 바꿀 수 없게 되어있고, 이를 바꾸려고 하면 에러가 발생함
함수의 매개변수를 수정하고 함수가 끝난 뒤에도 이를 지속하려면 inout 파라미터로 정의해야함
func printName(name: String) {
name = "가짜 이름" // 에러 발생 Cannot assign to value: 'name' is a 'let' constant
print(name)
}
name 파라미터는 상수이기 때문에 바꿀 수 없다고 에러 뿜뿜
inout 파라미터는 이미 정의된 변수를 파라미터로 받고, 그 변수를 바꿀 수 있게 만들어줌
따라서 상수를 받을 수 없음
사용할때는 함수를 호출할 때 &문자를 같이 사용해야함(변경 될 수 있다는 뜻)
let realName = "철수"
func printName(name: inout String) {
name = "가짜 이름은 영수"
print(name)
}
printName(name: &realName) // 에러 발생 Cannot pass immutable value as inout argument: 'realName' is a 'let' constant
상수인 아규먼트는 에러 발생
var realName = "철수"
func printName(name: inout String) {
name = "가짜 이름은 영수"
print(name)
}
printName(name: &realName) // 가짜 이름은 영수
print(realName) // 가짜 이름은 영수
변수인 아규먼트를 파라미터로 받아서 함수내에서 바꿀 수 있고, 이는 함수 외부에 있는 변수에 직접적인 영향을 미침
값을 반환하는 것과는 다른 것임(printName 함수는 반환 값이 없음)
Inout의 작동
- 함수가 호출될 때, argumnet의 값이 복사됨
- 함수 내에서 복사된 값이 수정됨
- 함수가 끝날 때, 복사된 값이 원래 argument에 할당됨
이 동작은 copy-In copy-Out 또는 call by value result 라고 함
연산프로퍼티나 프로퍼티 옵저버가 있는 상황에서 inout 파라미터를 받으면, getter가 호출되고 함수 반환으로 setter가 호출됨
Within a function, don’t access a value that was passed as an in-out argument, even if the original value is available in the current scope. Accessing the original is a simultaneous access of the value, which violates Swift’s memory exclusivity guarantee. For the same reason, you can’t pass the same value to multiple in-out parameters.
오리지널 값이 함수 내에서 사용가능하더라도, inout 아규먼트로 받은 값에 접근하면 안됨
inout 키워드로 다른 변수를 함수내에서 사용할 수 있더라도, 원본에 동시에 접근하게 되면 메모리 배타성 보장을 위반할 수 있다
같은 이유로 동일한 값을 여러 inout 파라미터로 사용할 수 없음
var realName = "철수"
func printName(name: inout String, secondName: inout String) {
name = "가짜 이름은 영수"
secondName = "두번째 이름도 영수"
print(name)
print(secondName)
}
printName(name: &realName, secondName: &realName)
// 에러 발생 Inout arguments are not allowed to alias each other
// Overlapping accesses to 'realName', but modification requires exclusive access; consider copying to a local variable
클로저나 중첩함수에서 inout 매개변수를 사용하는 경우에는 논이스케이핑 클로저이어야함
매개변수를 변경하지 않고 캡쳐해야하는 경우에는 캡쳐리스트를 사용해서 변하지 않도록 해야함
매개변수를 캡쳐한 뒤 이를 변경해야 한다면 로컬 복사를 사용해야하고, 함수가 끝나기 전에 모든 변경이 끝나는 멀티 쓰레드 코드를 사용해야함(잘 이해 안됨)