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

关于从函数参数中删除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()
    }
}

我只在数组上使用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
}

我认为您应该按照本次讨论中给出的建议使用inout

放在上下文中,在您的示例中:

public func getQuestionList(var language: String) 

应替换为:

public func getQuestionList(language: inout String) 

最新更新