web-dev-qa-db-fra.com

Les paramètres 'var' sont obsolètes et seront supprimés dans Swift 3

Très bien, je viens de mettre à jour Xcode vers 7.3 et maintenant je reçois cet avertissement:

Les paramètres 'var' sont obsolètes et seront supprimés dans Swift 3

Comment résoudre ce problème lorsque j'ai besoin d'utiliser la var dans cette fonction:

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()
}
113
SDW

Avez-vous essayé d'assigner à une nouvelle var

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()
}
81
garanda

La discussion sur la suppression de Var d'un paramètre de fonction est entièrement documentée dans cette soumission sur GitHub: Remove Var Parameters

Dans ce document, vous constaterez que les gens confondent souvent les paramètres var avec les paramètres inout. Un paramètre var signifie simplement que le paramètre est modifiable dans le contexte de la fonction, tandis qu'avec un paramètre inout, la valeur du paramètre au point de retour sera copiée hors de la fonction et dans le contexte de l'appelant.

La bonne façon de résoudre ce problème consiste à supprimer var du paramètre et à introduire une variable locale var. En haut de la routine, copiez la valeur du paramètre dans cette variable.

96
Tr0yJ

Ajoutez simplement cette ligne au début de la fonction:

var language = language

et le reste de votre code peut rester inchangé, comme ceci:

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()
}
60
Harris

Beaucoup de gens suggèrent un paramètre inout, mais ce n'est pas vraiment ce pour quoi ils ont été conçus. De plus, il ne permet pas d'appeler la fonction avec une constante let, ni avec un littéral de chaîne. Pourquoi ne pas simplement ajouter la valeur par défaut à la signature de la fonction?

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

Assurez-vous simplement de ne pas appeler getQuestionList avec la chaîne vide au cas où vous voudriez utiliser la langue par défaut, mais laissez de côté le paramètre:

let list = getQuestionList() // uses the default "NL" language
13
Tim Vermeulen
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()

}

1
Abdul Rahman Khan

Swift 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)

Dans certains cas, comme je l'ai déjà vu (avec des configurations plus complexes impliquant des tableaux), la création d'une nouvelle propriété dans la méthode et la mutation de cette propriété peuvent ne pas toujours fonctionner. De plus, vous encombrez la méthode au lieu d’ajouter simplement inout à un paramètre et & à son argument, ce pour quoi cette syntaxe a été créée.

1
bsod

Je pense que les réponses de @Harris et @garanda sont la meilleure approche.

Quoi qu'il en soit, dans votre cas, vous n'avez pas besoin de var, vous pouvez faire:

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
Simone Pistecchia

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

Paramètres In-Out

Les paramètres de fonction sont des constantes par défaut. Tenter de modifier la valeur d'un paramètre de fonction à partir du corps de cette fonction entraîne une erreur lors de la compilation. Cela signifie que vous ne pouvez pas modifier la valeur d’un paramètre par erreur. Si vous souhaitez qu'une fonction modifie la valeur d'un paramètre et que ces modifications soient conservées une fois l'appel de la fonction terminé, définissez ce paramètre en tant que paramètre in-out.

Vous écrivez un paramètre in-out en plaçant le mot clé inout juste avant le type d'un paramètre. Un paramètre in-out a une valeur transmise à la fonction, modifiée par la fonction et renvoyée hors de la fonction pour remplacer la valeur d'origine. Pour une discussion détaillée du comportement des paramètres d'entrée-sortie et des optimisations associées du compilateur, voir Paramètres d'entrée-sortie.

Vous pouvez uniquement transmettre une variable en tant qu'argument d'un paramètre in-out. Vous ne pouvez pas transmettre une constante ou une valeur littérale en tant qu'argument, car les constantes et les littéraux ne peuvent pas être modifiés. Vous placez un esperluette (&) directement devant le nom d'une variable lorsque vous le transmettez en tant qu'argument à un paramètre in-out, pour indiquer qu'il peut être modifié par la fonction.

REMARQUE

Les paramètres In-Out ne peuvent pas avoir de valeurs par défaut et les paramètres variadic ne peuvent pas être marqués comme inout.

Voici un exemple de fonction appelée swapTwoInts (: :), qui possède deux paramètres entiers en entrée appelés a et b:

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

La fonction swapTwoInts (: :) substitue simplement la valeur de b en a et la valeur de a en b. La fonction effectue cet échange en stockant la valeur de a dans une constante temporaire appelée temporaireA, en attribuant la valeur de b à a, puis en affectant temporaireA à b.

Vous pouvez appeler la fonction swapTwoInts (: :) avec deux variables de type Int pour échanger leurs valeurs. Notez que les noms de someInt et anotherInt sont préfixés par une perluète lorsqu'ils sont passés à 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"

L'exemple ci-dessus montre que les valeurs d'origine de someInt et anotherInt sont modifiées par la fonction swapTwoInts (: :), même si elles ont été définies à l'extérieur de la une fonction.

REMARQUE

Les paramètres d'entrée-sortie ne correspondent pas au retour d'une valeur d'une fonction. L'exemple swapTwoInts ci-dessus ne définit pas un type de retour ni une valeur, mais il modifie néanmoins les valeurs de someInt et anotherInt. Les paramètres In-Out sont un moyen alternatif pour une fonction d'avoir un effet en dehors de la portée de son corps de fonction.

0
Mustafa Mohammed

Voici une autre idée. Mon cas d'utilisation était de passer un tableau de chaînes à y ajouter, pour lequel le tableau devait être passé mutuellement. Je ne voulais pas avoir d'état dans ma classe pour cela non plus. J'ai donc créé une classe qui contient le tableau et le passe. En fonction de votre cas d'utilisation, il peut sembler idiot de disposer d'une classe contenant uniquement cette variable.

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

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

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

J'utilise uniquement les méthodes append et joined sur le tableau, il était donc facile de changer le type avec un minimum d'autres modifications apportées à mon code.

Quelques exemples d'utilisation:

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
}
0
webjprgm