티스토리 뷰

! 공식문서를 참고한 글입니다

 

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의 작동

  1. 함수가 호출될 때, argumnet의 값이 복사됨
  2. 함수 내에서 복사된 값이 수정됨
  3. 함수가 끝날 때, 복사된 값이 원래 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 매개변수를 사용하는 경우에는 논이스케이핑 클로저이어야함

매개변수를 변경하지 않고 캡쳐해야하는 경우에는 캡쳐리스트를 사용해서 변하지 않도록 해야함

 

매개변수를 캡쳐한 뒤 이를 변경해야 한다면 로컬 복사를 사용해야하고, 함수가 끝나기 전에 모든 변경이 끝나는 멀티 쓰레드 코드를 사용해야함(잘 이해 안됨)

 

자세한건
https://docs.swift.org/swift-book/documentation/the-swift-programming-language/declarations/#In-Out-Parameters

 

 

 

 

 

 

 

 

댓글