好的,所以我只是将Xcode更新为7.3,现在我收到了这个警告:
'无功'参数已弃用,将在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()
}
答案 0 :(得分:95)
关于从函数参数中删除Var的讨论已完全记录在GitHub上的这个提交中:Remove Var Parameters
在该文档中,您会发现人们常常将var
参数与inout
参数混淆。 var
参数只是意味着参数在函数的上下文中是可变的,而使用inout
参数时,返回点处参数的值将被复制出函数并进入来电者的背景。
解决此问题的正确方法是从参数中删除var
并引入本地var
变量。在例程的顶部将参数的值复制到该变量中。
答案 1 :(得分:81)
您是否尝试过分配新的
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 :(得分:58)
只需在函数开头添加这一行:
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()
}
答案 3 :(得分: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
答案 4 :(得分:1)
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()
}
答案 5 :(得分:1)
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)
在某些情况下,正如我所经历的(涉及数组的更复杂的设置),在方法中创建新属性并改变该属性可能并不总是有效。更不用说,您将方法混乱,而不是简单地将inout
附加到参数,并将&
附加到其参数,这就是为此创建的语法。
答案 6 :(得分: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()
}
答案 7 :(得分:0)
输入输出参数
默认情况下,函数参数是常量。尝试从该函数体内更改函数参数的值会导致编译时错误。这意味着您无法错误地更改参数的值。如果您希望函数修改参数的值,并且希望在函数调用结束后这些更改仍然存在,请将该参数定义为输入输出参数。
您可以通过将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的值存储在名为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"
上面的示例显示someTnt和anotherInt的原始值由swapTwoInts(: :)函数修改,即使它们最初是在函数外部定义的。
请注意
输入输出参数与从函数返回值不同。上面的swapTwoInts示例没有定义返回类型或返回值,但它仍然修改了someInt和anotherInt的值。输入输出参数是函数在其函数体范围之外产生效果的另一种方法。
答案 8 :(得分: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
}