입출력 매개 변수를 언제 사용합니까?
클래스 또는 기본 유형을 함수에 전달할 때 매개 변수에 대한 함수의 변경 사항은 클래스 외부에 반영됩니다. 이것은 기본적으로 inout
매개 변수가 수행해야하는 것과 동일 합니다.
inout 매개 변수의 좋은 사용 사례는 무엇입니까?
inout
즉, 지역 변수를 수정하면 전달 된 매개 변수도 수정됩니다. 이것이 없으면 전달 된 매개 변수는 동일한 값으로 유지됩니다. 사용할 때 참조 유형을 생각 inout
하고 사용하지 않고 값 유형 을 생각 하십시오.
예를 들면 :
import UIKit
var num1: Int = 1
var char1: Character = "a"
func changeNumber(var num: Int) {
num = 2
print(num) // 2
print(num1) // 1
}
changeNumber(num1)
func changeChar(inout char: Character) {
char = "b"
print(char) // b
print(char1) // b
}
changeChar(&char1)
좋은 사용 사례는 swap
전달 된 매개 변수를 수정하는 함수입니다.
스위프트 3+ 참고 : 스위프트 3부터가 의 inout
키워드는 와야 후 콜론과 형식 앞에. 예를 들어, Swift 3+는 이제 func changeChar(char: inout Character)
.
에서 선언 - 인 - 아웃 파라미터 : 애플 언어 참조 :
최적화로, 인수가 메모리의 물리적 주소에 저장된 값인 경우 함수 본문 내부와 외부에서 동일한 메모리 위치가 사용됩니다. 최적화 된 동작을 참조에 의한 호출이라고합니다. 카피 인 카피 아웃 모델의 모든 요구 사항을 충족하는 동시에 카피 오버 헤드를 제거합니다 . 카피 인 카피 아웃과 참조에 의한 호출 사이의 동작 차이에 의존하지 마십시오.
다소 메모리 측면에서 큰 값 유형을 인수로 사용하고 (예 : 큰 구조 유형) 동일한 유형을 반환하는 함수가 있고 마지막으로 함수 반환이 항상 호출자 인수를 대체하는 데 사용되는 경우 다음 inout
과 같습니다. 연관된 함수 매개 변수로 선호합니다.
아래의 예를 살펴 보겠습니다. 주석이 여기 inout
에 일반 type-in-return-type 함수 를 사용 하는 이유를 설명 합니다.
struct MyStruct {
private var myInt: Int = 1
// ... lots and lots of stored properties
mutating func increaseMyInt() {
myInt += 1
}
}
/* call to function _copies_ argument to function property 'myHugeStruct' (copy 1)
function property is mutated
function returns a copy of mutated property to caller (copy 2) */
func myFunc(var myHugeStruct: MyStruct) -> MyStruct {
myHugeStruct.increaseMyInt()
return myHugeStruct
}
/* call-by-reference, no value copy overhead due to inout opimization */
func myFuncWithLessCopyOverhead(inout myHugeStruct: MyStruct) {
myHugeStruct.increaseMyInt()
}
var a = MyStruct()
a = myFunc(a) // copy, copy: overhead
myFuncWithLessCopyOverhead(&a) // call by reference: no memory reallocation
또한 위의 예에서 ---- 메모리 문제를 무시 ---- inout
우리 코드를 읽는 사람에게 우리가 함수 호출자 인수 (함수 &
에서 인수 앞에 앰퍼샌드로 암시 적으로 표시됨)를 변경하고 있음을 알리는 좋은 코드 관행으로 선호 될 수 있습니다. 요구). 다음은 이것을 아주 깔끔하게 요약합니다.
함수가 매개 변수 값을 수정하도록하고 함수 호출이 종료 된 후에도 이러한 변경 사항을 유지하려면 해당 매개 변수를 대신 in-out 매개 변수로 정의하십시오.
에서 - 인 - 아웃 매개 변수 기능 : 애플 언어 가이드 .
자세한 내용과 inout
메모리에서 실제로 처리되는 방법 (이름 copy-in-copy-out
은 다소 오해의 소지가 있습니다 ...)-위의 언어 가이드 링크에 추가로 ---- 다음 SO 스레드를 참조하십시오.
(추가 편집 : 추가 메모)
위의 Lucas Huang이 수락 한 답변에 주어진 예는 inout
인수를 사용하는 함수 범위에서 인수로 전달 된 변수에 액세스 하려고합니다 inout
. 이것은 권장되지 않으며 ref 언어에서하지 않도록 명시 적으로 경고합니다.
원래 인수가 현재 범위에서 사용 가능하더라도 in-out 인수로 전달 된 값에 액세스하지 마십시오 . 함수가 반환되면 원본에 대한 변경 사항을 복사본 값으로 덮어 씁니다. 변경 사항을 덮어 쓰지 않도록하기 위해 참조 별 호출 최적화 구현에 의존하지 마십시오 .
이제이 경우 액세스는 "오직"변경할 수 없습니다 (예 :) print(...)
. 그러나 이와 같은 모든 액세스는 관례 상 피해야합니다.
댓글 작성자의 요청에 따라 "인-아웃 인수로 전달 된 값"으로 실제로 아무것도하지 말아야하는 이유를 설명하는 예제를 추가하겠습니다 .
struct MyStruct {
var myStructsIntProperty: Int = 1
mutating func myNotVeryThoughtThroughInoutFunction (inout myInt: Int) {
myStructsIntProperty += 1
/* What happens here? 'myInt' inout parameter is passed to this
function by argument 'myStructsIntProperty' from _this_ instance
of the MyStruct structure. Hence, we're trying to increase the
value of the inout argument. Since the swift docs describe inout
as a "call by reference" type as well as a "copy-in-copy-out"
method, this behaviour is somewhat undefined (at least avoidable).
After the function has been called: will the value of
myStructsIntProperty have been increased by 1 or 2? (answer: 1) */
myInt += 1
}
func myInoutFunction (inout myInt: Int) {
myInt += 1
}
}
var a = MyStruct()
print(a.myStructsIntProperty) // 1
a.myInoutFunction(&a.myStructsIntProperty)
print(a.myStructsIntProperty) // 2
a.myNotVeryThoughtThroughInoutFunction(&a.myStructsIntProperty)
print(a.myStructsIntProperty) // 3 or 4? prints 3.
따라서이 경우 입력은 참조가 아닌 복사 복사로 동작합니다. 언어 참조 문서에서 다음 문장을 반복하여 요약합니다.
카피 인 카피 아웃과 참조에 의한 호출 사이의 동작 차이에 의존하지 마십시오.
Function parameters are constants by default. Trying to change the value of a function parameter from within the body of that function results in a compile-time error. This means that you can’t change the value of a parameter by mistake. If you want a function to modify a parameter’s value, and you want those changes to persist after the function call has ended, define that parameter as an in-out parameter instead.
inout parameter allow us to change the data of a value type parameter and to keep changes still after the function call has finished.
If you work with classes then, as you say, you can modify the class because the parameter is a reference to the class. But this won't work when your parameter is a value type (https://docs.swift.org/swift-book/LanguageGuide/Functions.html - In-Out Parameters Section)
One good example of using inout is this one (defining math for CGPoints):
func + (left: CGPoint, right: CGPoint) -> CGPoint {
return CGPoint(x: left.x + right.x, y: left.y + right.y)
}
func += (left: inout CGPoint, right: CGPoint) {
left = left + right
}
Basically it is useful when you want to play with addresses of variable its very useful in data structure algorithms
when use inout parameter swift 4.0 Work
class ViewController: UIViewController {
var total:Int = 100
override func viewDidLoad() {
super.viewDidLoad()
self.paramTotal(total1: &total)
}
func paramTotal(total1 :inout Int) {
total1 = 111
print("Total1 ==> \(total1)")
print("Total ==> \(total)")
}
}
참고URL : https://stackoverflow.com/questions/34486052/when-to-use-inout-parameters
'code' 카테고리의 다른 글
터미널에서 단일 라인 SFTP (0) | 2020.11.13 |
---|---|
React로 예쁜 인쇄 JSON (0) | 2020.11.13 |
JSON.stringify에 해당하는 jquery (0) | 2020.11.12 |
5 백만 개 이상의 레코드에 대한 MongoDB 쿼리 성능 (0) | 2020.11.12 |
IOS 프로젝트에서“내부 오류가 발생했습니다. (0) | 2020.11.12 |