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


120

좋아, Xcode를 7.3으로 업데이트하고 이제 다음 경고가 표시됩니다.

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

이 함수에서 var를 사용해야 할 때이 문제를 해결하는 방법 :

public func getQuestionList(var language: String) -> NSArray {
    if self.data.count > 0 {
        if (language.isEmpty) {
            language = "NL"
        }
        return self.data.objectForKey("questionList" + language) as! NSArray
    }

    return NSArray()
}

6
어떻습니까public func getQuestionList(inout language: String) -> NSArray
— TotoroTotoro

2
아니요, 이것은 적절한 대체품이 아닙니다. OP는 아마도 getQuestion부작용을 원하지 않을 것입니다 .
— BallpointBen

5
나는 솔직히 그들이 이것을 제거하는 것을 고려하는 이유를 모른다. 스위프트를 멋지게 만든 기능 중 하나였습니다!
— Danny Bravo

직접 사용하지 않았고 소란을 이해하지 못했습니다.
— Mike Taverne

@MikeTaverne (늦은 응답) 다음 기능을 고려하십시오 func foo(_ bar: int) { /*use bar*/ bar+=1; foo(bar); }.. 이것은 var params 없이는 불가능합니다. 함수 내에 별도의 var를 만들고 값을 복사하거나 매개 변수를 inout으로 표시해야합니다. 전자는 느리고 후자는 정의되지 않은 동작을 유발합니다. 많은 알고리즘이 이와 같은 재귀를 사용합니다.
— kevin

답변:


82

새 변수에 할당하려고 했습니까?

public func getQuestionList(language: String) -> NSArray {
    var lang = language
    if self.data.count > 0 {
        if (lang.isEmpty) {
            lang = "NL"
        }
        return self.data.objectForKey("questionList" + lang) as! NSArray
    }

    return NSArray()
}

11
아니 정말 영업이 원하는 생각
— 유황

6
@garana와 같은 방식으로 OP의 질문을 이해했을 것입니다. OP는 질문에서 inout을 사용하지 않고 기존 변수를 로컬로 변경 합니다.
— Eric Aya

11
실제로 이것은 올바른 해결책입니다. 이 변화를 제안 스위프트의 진화 문제를 참조하십시오 github.com/apple/swift-evolution/blob/master/proposals/...
— 스콧 톰슨

8
@TimVermeulen 누구나 진보적 인 언어를 사용하고 싶어합니다. Apple은 매월 구문을 변경하지 않고 다양한 방법으로 언어를 개발할 수 있습니다. 아시다시피, 수많은 온라인 문서와 코드 조각이 Apple로 인해 만료되었거나 오래되었습니다. 개발자들은이 사이트를 방문하여 많은 어리석은 질문에 대한 도움을 반복적으로 요청해야합니다. Apple이 더 많은 개발자가 능숙하기를 원한다면 구문은 처음부터 견고해야합니다.
— TomSawyer

25
다른 변수 이름을 도입하지 않으려면 var language = language를 사용하십시오 (처음에 imo에서 var 매개 변수의 주요 이점이었습니다)
— Harris

102

함수 매개 변수에서 Var를 제거하는 방법에 대한 논의는 GitHub : Remove Var Parameters 의이 제출에 완전히 문서화되어 있습니다.

이 문서에서 사람들은 종종 var매개 변수와 inout매개 변수를 혼동 합니다. var파라미터는 단순히 함께하면서 파라미터 함수의 문맥 내에서 변경할 수 있음을 의미 inout파라미터 반환 지점에서 파라미터의 값은 함수 및 발신자의 상황에 내보내는 것이다.

이 문제를 해결하는 올바른 방법 var은 매개 변수에서 제거 하고 지역 var변수를 도입하는 것 입니다. 루틴의 맨 위에서 매개 변수 값을 해당 변수에 복사하십시오.


44
이 변경 사항을 전혀 이해하지 못합니다. 변경 가능한 로컬 변수를 만들기 위해 다른 줄을 작성해야하는 이유는 매개 변수를 변수로 정의하는 것보다 낫습니다.
— Ross Barbish 2016 년

나에게이 변경은 내가 지역 변수를 구현해야하는 상황을 선택하기 때문에 좋다. 그러나 나는 쉬운 방법을 취하고 입력 매개 변수를 var로 만드는 (이전) Swift의 제안을 받아 들였기 때문에 그렇게하지 않았다
— dawid

1
나는 이것에 대해 @RossBarbish와 함께 있습니다. 그래서 ... 게으른 개발자가 inout과 var 매개 변수를 구분할 수 없기 때문에 제거되고 있습니까? Pfff ...
— Danny Bravo

1
이것은 몹시 불필요한 것 같습니다 ... 두 옵션을 모두 유지 했어야합니다.
— Oscar Gomez

1
아마도 swift는 어쨌든 장면 뒤에서 매개 변수 위에 지역 변수를 선언하고 있었을 것입니다. 이제 수동으로해야합니다. 성능에는 변화가 없지만 단순한 개념으로 초보자를 돕기 위해 편의성을 잃었습니다.
— mogelbuster

62

함수 시작 부분에 다음 한 줄을 추가하면됩니다.

var language = language

나머지 코드는 다음과 같이 변경되지 않을 수 있습니다.

public func getQuestionList(language: String) -> NSArray {
    var language = language
    if self.data.count > 0 {
        if (language.isEmpty) {
            language = "NL"
        }
        return self.data.objectForKey("questionList" + language) as! NSArray
    }

    return NSArray()
}

5
지금까지 최고의 답변입니다. 한 줄만 변경하면됩니다.
— BallpointBen

하지만 너무 부자연스러워 보입니다
— @James

1
이름이 같기 때문에 이것이 최고의 답이라고 생각합니다. 다른 일반적인 언어와 비슷합니다.
— 이오 니스트

1
@RiverSatya 매개 변수를 직접 사용하지 않는 이유는 무엇입니까?
— Declan McKenna

1
정말 멋진 제안입니다. 우리는 Swiftify에서 이런 방식으로 구현할 것입니다. :)
— Crulex

13

많은 사람들이 inout매개 변수를 제안하고 있지만 그것이 실제로 그들이 설계된 것이 아닙니다. 게다가 let상수 나 문자열 리터럴로 함수를 호출 할 수 없습니다 . 함수 서명에 단순히 기본값을 추가하지 않는 이유는 무엇입니까?

public func getQuestionList(language language: String = "NL") -> NSArray {
    if data.count > 0 {
        return data.objectForKey("questionList" + language) as! NSArray
    } else {
        return NSArray()
    }
}

getQuestionList기본 언어를 원할 경우 빈 문자열로 호출하지 말고 매개 변수를 생략하십시오.

let list = getQuestionList() // uses the default "NL" language

3
모두가 영업 이익은 심지어 처음에 ... 사용하지 않은 경우 입출력 솔루션에 뛰어 이유는 이해가 안 돼요
— 에릭 아야

1
그들은 var와 inout이 같은 일을한다고 가정했습니다.
— ryantxr

2

스위프트 4

public func getQuestionList(language: inout String) -> NSArray {
    if self.data.count > 0 {
        if (language.isEmpty) {
            language = "NL"
        }
        return self.data.objectForKey("questionList" + language) as! NSArray
    }

    return NSArray()
}

getQuestionList(language: &someString)

어떤 경우에는 (배열과 관련된 더 복잡한 설정으로) 경험했듯이 메서드 내에서 새 속성을 만들고 해당 속성을 변경하는 것이 항상 작동하지 않을 수 있습니다. 말할 것도없이, inout매개 변수와 &인수 에 단순히 추가 하는 대신 메서드를 복잡하게 만드는데, 이것이이 구문이 만들어진 이유입니다.



0

@Harris와 @garanda 답변이 최선의 접근 방식이라고 생각합니다.

어쨌든 귀하의 경우에는 var가 필요하지 않습니다.

public func getQuestionList(language: String) -> NSArray {
    if self.data.count > 0 {
        return self.data.objectForKey("questionList" + (language.isEmpty ? "NL" : language)) as! NSArray
    }
    return NSArray()
}

0

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Functions.html

인-아웃 매개 변수

함수 매개 변수는 기본적으로 상수입니다. 해당 함수의 본문 내에서 함수 매개 변수의 값을 변경하려고하면 컴파일 타임 오류가 발생합니다. 이는 실수로 매개 변수 값을 변경할 수 없음을 의미합니다. 함수가 매개 변수 값을 수정하도록하고 함수 호출이 종료 된 후에도 이러한 변경 사항이 유지되도록하려면 해당 매개 변수를 대신 in-out 매개 변수로 정의하십시오.

매개 변수 유형 바로 앞에 inout 키워드를 배치하여 in-out 매개 변수를 작성합니다. 인-아웃 매개 변수에는 함수에 전달되고 함수에 의해 수정되고 원래 값을 대체하기 위해 함수에서 다시 전달되는 값이 있습니다. in-out 매개 변수 및 관련 컴파일러 최적화의 동작에 대한 자세한 설명은 In-Out 매개 변수를 참조하십시오.

in-out 매개 변수에 대한 인수로만 변수를 전달할 수 있습니다. 상수와 리터럴은 수정할 수 없으므로 상수 또는 리터럴 값을 인수로 전달할 수 없습니다. in-out 매개 변수에 인수로 전달할 때 변수 이름 바로 앞에 앰퍼샌드 (&)를 배치하여 함수가 수정할 수 있음을 나타냅니다.

노트

In-out 매개 변수는 기본값을 가질 수 없으며 가변 매개 변수는 inout으로 표시 될 수 없습니다.

다음 은 a와 b라는 두 개의 인-아웃 정수 매개 변수가있는 swapTwoInts ( : :) 라는 함수의 예입니다 .

func swapTwoInts(_ a: inout Int, _ b: inout Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}

swapTwoInts ( : :) 함수는 b의 값을 a로, a의 값을 b로 바꿉니다 . 이 함수는 a 값을 temporaryA라는 임시 상수에 저장하고 b 값을 a에 할당 한 다음 temporaryA를 b에 할당하여이 스왑을 수행합니다.

Int 유형의 두 변수를 사용 하여 swapTwoInts ( : :) 함수를 호출하여 값을 바꿀 수 있습니다. someInt 및 anotherInt의 이름은 swapTwoInts ( : :) 함수에 전달 될 때 앰퍼샌드로 시작됩니다 .

var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
print("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
// Prints "someInt is now 107, and anotherInt is now 3"

위의 예는 someInt 및 anotherInt의 원래 값 이 원래 함수 외부에서 정의 되었음에도 불구 하고 swapTwoInts ( : :) 함수에 의해 수정되는 것을 보여줍니다 .

노트

인-아웃 매개 변수는 함수에서 값을 반환하는 것과 다릅니다. 위의 swapTwoInts 예제는 반환 유형을 정의하거나 값을 반환하지 않지만 여전히 someInt 및 anotherInt의 값을 수정합니다. 인-아웃 매개 변수는 함수가 함수 본문의 범위를 벗어난 효과를 갖는 다른 방법입니다.


0

여기 또 다른 아이디어가 있습니다. 내 사용 사례는 추가 할 문자열 배열을 전달하는 것이 었는데, 배열은 변경 가능하게 전달되어야합니다. 나는 이것에 대해 내 수업에 상태를 갖고 싶지 않았습니다. 그래서 저는 배열을 보유하고 전달하는 클래스를 만들었습니다. 사용 사례에 따라 하나의 변수 만 보유하는 클래스를 갖는 것이 어리석은 것처럼 보일 수 있습니다.

private class StringBuilder {
    var buffer: [String] = []

    func append(_ str: String) {
        buffer.append(str)
    }

    func toString() -> String {
        return buffer.joined()
    }
}

나는 사용 append하고joined배열에서 메서드 하므로 코드를 최소한으로 변경하여 유형을 쉽게 변경할 수있었습니다.

사용 예 :

private func writeMap(map: LevelMap, url: URL) -> Bool {
    let buffer = StringBuilder()

    if !writeHeader(map: map, buffer: buffer) {
        return false
    }
    if !writeFloors(map: map, buffer: buffer) {
        return false
    }

    let content = buffer.toString()
    do {
        try content.write(to: url, atomically: true, encoding: .utf8)
        return true
    } catch {}
    return false
}

private func writeHeader(map: LevelMap, buffer: StringBuilder) -> Bool {
    buffer.append("something here ...\n")
    return true
}

내 대답은 발신자가 본 원래 값을 수정하려는 경우입니다. 값을 로컬로 재 할당 할 수 있지만 호출자에게 영향을주지 않으려는 경우 위의 다른 답변이이를 처리합니다.
— webjprgm
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.