好吧,所以我只是将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()
}
关于从函数参数中删除Var的讨论在GitHub上的提交文件中有完整的文档:删除Var参数
在该文档中,您会发现人们经常将var
参数与inout
参数混淆。var
参数简单地表示该参数在函数的上下文中是可变的,而对于inout
参数,返回点处的参数值将从函数中复制到调用方的上下文中。
解决这个问题的正确方法是从参数中删除var
,并引入局部var
变量。在例程的顶部,将参数的值复制到该变量中。
您是否尝试分配给新的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()
}
只需在函数的开头添加一行:
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()
}
很多人建议使用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
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()
}
我认为@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()
}
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Functions.html
输入输出参数
默认情况下,函数参数是常量。试图从函数体中更改函数参数的值会导致编译时错误。这意味着您不能错误地更改参数的值。如果希望函数修改参数的值,并且希望这些更改在函数调用结束后保持不变,请将该参数定义为in-out参数。
通过将inout关键字放在参数的类型之前,可以编写一个in-out参数。输入输出参数的值传入函数,由函数修改,然后从函数中返回以替换原始值。有关输入输出参数行为和相关编译器优化的详细讨论,请参阅输入输出参数。
只能传递一个变量作为输入输出参数的参数。不能传递常量或文字值作为参数,因为常量和文字无法修改。当您将变量作为参数传递给输入输出参数时,您可以在变量名称的正前方放置一个与号(&),以指示该函数可以对其进行修改。
注意
输入-输出参数不能有默认值,变参数不能标记为输入-输出。
下面是一个名为swapTwoInts(::)的函数示例,它有两个名为a和b:的输入输出整数参数
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类型的两个变量调用swapTwoInt(::)函数来交换它们的值。请注意,someInt和anotherInt的名称在传递给swapTwoInt(::)函数时会以"与"作为前缀:
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的原始值由swapTwoInt(::)函数修改,即使它们最初是在函数之外定义的。
注意
输入输出参数与从函数返回值不同。上面的swapTwoInts示例没有定义返回类型或返回值,但它仍然修改someInt和anotherInt的值。输入输出参数是函数在其函数体范围之外产生效果的一种替代方式。
这是另一个想法。我的用例是传递一个字符串数组以附加到它,对于它,必须可变地传入数组。我也不想在课堂上出现这种状态。所以我创建了一个类来保存数组并传递它。根据您的用例,只包含一个变量的类可能看起来很傻。
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
}
我认为您应该按照本次讨论中给出的建议使用inout
。
放在上下文中,在您的示例中:
public func getQuestionList(var language: String)
应替换为:
public func getQuestionList(language: inout String)