'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.