Swift make 메소드 매개 변수를 변경할 수 있습니까?


123

추가 변수를 생성하지 않고이 오류를 어떻게 처리 할 수 ​​있습니까?

func reduceToZero(x:Int) -> Int {
    while (x != 0) {
        x = x-1            // ERROR: cannot assign to 'let' value 'x'
    }
    return x
}

x 값을 저장하기 위해 추가 변수를 만들고 싶지 않습니다. 내가 원하는 것을 할 수 있습니까?


3
아래 업데이트 된 답변을 참조하십시오 .Swift 3는 수락 된 답변을 더 이상 사용하지 않습니다.
achi

답변:


192

다른 답변에서 언급했듯이 Swift 3에서 변수 앞에 var를 배치하면 더 이상 사용되지 않습니다. 다른 답변에는 언급되어 있지 않지만 inout매개 변수 를 선언하는 기능 입니다. 생각하십시오 : 포인터를 전달하십시오.

func reduceToZero(_ x: inout Int) {
    while (x != 0) {
        x = x-1     
    }
}

var a = 3
reduceToZero(&a)
print(a) // will print '0'

이것은 재귀에서 특히 유용 할 수 있습니다.

Apple의 inout선언 지침은 여기 에서 찾을 수 있습니다 .


2
대단히 감사합니다 !!!! 나는 재귀 질문에 갇혀 있습니다. 당신은 내 생명을 구했습니다.
JW.ZG

2
함수 범위 밖의 변수를 수정하므로주의해서 사용해야합니다. 이상적으로는 함수 내에서 변경 한 값을 명시 적으로 반환하려고합니다.
Chris Gunawardena

2
inout키워드는 func reduceToZero(x: inout Int) 현재 Swift 3 버전에서 와 같이 매개 변수 이름과 매개 변수 유형 사이에 배치되어야합니다 .
Agustí Sánchez

클로저는 분명히 값으로 만 입력 매개 변수를 캡처하기 때문에 클로저에는 작동하지 않는 것 같습니다 (적어도 Xcode가 제공하는 오류 메시지입니다). 이 경우 @GeRyCh 솔루션을 사용합니다.
wcochran

감사합니다. 이것은 지금은 효과가 있었지만 C에서 포인터를 사용하는 것과 같습니다. 이것이 다른 Swift 버전에서도 살아남 을까요?
Krishna Vedula

45

'var'매개 변수는 더 이상 사용되지 않으며 Swift 3에서 제거됩니다. 따라서 새 매개 변수에 할당하는 것이 이제 가장 좋은 방법 인 것 같습니다.

func reduceToZero(x:Int) -> Int {
    var x = x
    while (x != 0) {
        x = x-1            
    }
    return x
}

여기에 언급 된대로 : 'var'매개 변수는 더 이상 사용되지 않으며 Swift 3에서 제거됩니다.


1
이 경우 실제로 x새 파일을 복사 var x합니까? 아니면 Swift가 그보다 더 효율적인 작업을하고 있습니까?
Genki

3
이것은 작동하고 내가하는 일이지만 매우 어색한 것 같습니다.
wcochran

1
@Gomfucius Swift 3.1 가이드에서 이것에 대한 단어가 아닙니다. 이 경우 ( x등록부에 적합) 사실상 비용이 없습니다. x변형 된 배열, 구조체 또는 객체 인 경우 거의 확실하게 복사를 수행해야합니다 (최적화 프로그램이이를 인라인으로 분석하고 별칭을 지정할 수없는 경우).
wcochran 2017

1
@wcochran 이것은 깔끔한 속임수이지만 실제로는 특별한 일이 없습니다. 단순히 로컬 var 사본으로 입력 매개 변수를 가려내는 것입니다. OP의 상황에서는 의도하지 않은 부작용이있을 수있는 var것보다 args를 대체하는 것이 더 좋습니다 inout. var가 포인터라면.
Echelon

45

Swift 1 및 2의 경우 (Swift 3의 경우 inout 매개 변수를 사용하여 achi의 답변 참조) : Swift의 함수 인수는 let기본적으로 있으므로 var값을 변경해야하는 경우로 변경합니다.

func reduceToZero(var x:Int) -> Int {
    while (x != 0) {
        x = x-1     
    }
    return x
}

2
이 답변이 지옥처럼 찬성 투표 한 이유는 무엇입니까? 다른 답변은이 답변 앞에 배치되었으며이 답변보다 더 많은 정보를 포함합니다.
Cristik

16
/! \ var를 사용하면 매개 변수에 전달 된 변수의 복사본이 생성됩니다. 따라서 수정해도 원래 값은 수정되지 않습니다. 또한 var매개 변수에 따라 새로운 스위프트 버전에서 사라질 가능성이 높다 github.com/apple/swift-evolution/blob/master/proposals/...
마티유 Riegler

17
메서드 paremeter의 var 키워드는 Swift 3에서 더 이상 사용되지 않습니다.
Boon

4
Swift 3에서는 더 이상이 작업을 수행 할 수 없습니다. 배열의 변수 복사본을 만들고 수정 된 배열을 반환해야합니다.
C0D3


14

가변 배열 포인터 전달에 대한 Swift3 답변.

함수:

func foo(array: inout Array<Int>) {
    array.append(1)
}

함수 호출 :

var a = Array<Int>()
foo(array:&a)

솔직히, 스위프트 그라운드가 끊임없이 변화하고 있기 때문에 이것이 올바른지 확실하지 않습니다. 복사본을 만들기 때문에 함수 내에서 var array = array를 수행하는 것보다 더 낫다고 생각했습니다 (실제로 원래 배열 구조에 영향을주지 않음)? 앞서 언급 한 var 접근 방식에 대한 더 나은 디자인 접근 방식이 있습니까?
joshd

7

Swift에서는 var함수 선언에서 변수 이름 앞에 키워드를 추가 하기 만하면됩니다 .

func reduceToZero(var x:Int) -> Int { // notice the "var" keyword
    while (x != 0) {
        x = x-1            
    }
    return x
}

Swift 책 의 "함수"장 (현재 iBook의 210 페이지) 에있는 "상수 및 변수 매개 변수"하위 섹션을 참조하십시오 .


7
'var'매개 변수는 더 이상 사용되지 않으며 Swift 3에서 제거됩니다
Regis St-Gelais

1
Swift 4 이상에서는 유효하지 않습니다.
ilkayaktas

0

우리가 사용하지 않는 경우가 있습니다 inout

변경 사항 / 범위가 함수 내부에만 있도록하려면 다음과 같이 사용할 수 있습니다.

func manipulateData(a: Int) -> Int {
    var a = a
    // ...
}

0

함수형 프로그래밍과 함께 Swift5를 사용하는 솔루션 ...

func reduceToZeroFP(x:Int) -> Int {
    x == 0 ? x : reduceToZeroFP(x: x - 1)
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.