Параметры "var" устарели и будут удалены в Swift 3
Хорошо, поэтому я просто обновляю 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()
}
Ответы
Ответ 1
Вы пытались назначить новый 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()
}
Ответ 2
Обсуждение удаления Var из параметра функции полностью задокументировано в этом представлении на GitHub: Удалить параметры Var
В этом документе вы обнаружите, что люди часто путают параметры var
с параметрами inout
. Параметр var
просто означает, что параметр изменен в контексте функции, а с параметром inout
значение параметра в точке возврата будет скопировано вне функции и в контексте вызывающего абонента.
Правильный способ решить эту проблему - удалить var
из параметра и ввести локальную переменную var
. В верхней части рутины скопируйте значение параметра в эту переменную.
Ответ 3
Просто добавьте эту строку в начале функции:
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()
}
Ответ 4
Многие люди предлагают параметр 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
Ответ 5
Я думаю, что ответы @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()
}
Ответ 6
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Functions.html
Параметры In-Out
Функциональные параметры по умолчанию являются константами. Попытка изменить значение параметра функции из тела этой функции приводит к ошибке времени компиляции. Это означает, что вы не можете изменить значение параметра по ошибке. Если вы хотите, чтобы функция изменяла значение параметра, и вы хотите, чтобы эти изменения сохранялись после завершения вызова функции, определите этот параметр как параметр in-out.
Вы записываете входной параметр, помещая ключевое слово inout прямо перед типом параметров. Параметр in-out имеет значение, которое передается функции, изменяется функцией и возвращается из функции для замены исходного значения. Подробное обсуждение поведения параметров in-out и связанных с ними оптимизаций компилятора см. В параметрах In-Out.
Вы можете передавать только переменную в качестве аргумента для параметра in-out. Вы не можете передать в качестве аргумента значение константы или буква, потому что константы и литералы не могут быть изменены. Вы помещаете амперсанд (&) непосредственно перед именем переменных, когда передаете его в качестве аргумента в параметр in-out, чтобы указать, что он может быть изменен функцией.
Примечание
Параметры вывода не могут иметь значения по умолчанию, а переменные параметры не могут быть помечены как inout.
Вот пример функции swapTwoInts (::), которая имеет два внутренних целых параметра a и b:
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
let temporaryA = a
a = b
b = temporaryA
}
Функция swapTwoInts (::) просто меняет значение b на a и значение a на b. Функция выполняет этот обмен, сохраняя значение a во временной константе, называемой временным А, присваивая значение b a, а затем назначая временным А на b.
Вы можете вызвать функцию swapTwoInts (::) с двумя переменными типа Int для обмена их значениями. Обратите внимание, что имена 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. Параметры in-out являются альтернативным способом для функции, которая имеет эффект вне области действия ее тела функции.
Ответ 7
Вот еще одна идея. Моим вариантом использования было передать массив строк для добавления к нему, для которого массив должен быть передан с изменчиво. Я тоже не хотел иметь состояние в своем классе. Поэтому я создал класс, содержащий массив и передающий его. В зависимости от вашего варианта использования может показаться глупым класс, содержащий только одну переменную.
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
}