‘ 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()
}
47635 次浏览

您是否尝试向一个新的 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()
}

很多人建议使用 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

关于从函数参数中删除 Var 的讨论在 GitHub: 删除 Var 参数的提交中有详细的文档说明

在该文档中,您会发现人们经常将 var参数与 inout参数混淆。var参数仅仅意味着参数在函数的上下文中是可变的,而使用 inout参数时,参数在返回点的值将被复制出函数并进入调用者的上下文。

解决这个问题的正确方法是从参数中删除 var并引入一个本地 var变量。在例程的顶部,将参数的值复制到该变量中。

只需在函数的开头添加一行:

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

我认为“哈里斯”和“加兰达”的回答是最好的方法。

不管怎样,在你的情况下,不需要 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()
}

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 参数不能有默认值,并且不能将可变参数标记为 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 的值存储在一个名为 tempharyA 的临时常量中,将 b 的值赋给 a,然后将 tempharyA 赋给 b。

可以使用 Int 类型的两个变量调用 swapTwoInts (::)函数来交换它们的值。请注意,在将 somInt 和 another Int 的名称传递给 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"

上面的示例显示了 somInt 和 another Int 的原始值被 swapTwoInts (::)函数修改,尽管它们最初是在函数之外定义的。

注意

In-out 参数与从函数返回值不同。上面的 swapTwoInts 示例没有定义返回类型或返回值,但是它仍然修改 somInt 和 another Int 的值。In-out 参数是函数在其函数体范围之外产生效果的一种替代方法。

还有一个办法。我的用例是传递一个字符串数组以附加到它,为此数组必须以可变方式传入。我也不想因为这个在我的课堂上出现状态。所以我创建了一个类来保存数组并传递它。根据用例的不同,使用一个只包含一个变量的类似乎有些愚蠢。

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


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


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

我只在数组上使用 appendjoined方法,所以很容易改变类型,对代码的其他更改也很少。

一些例子的用法:

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

}