'无功'参数已弃用,将在Swift 3中删除

时间:2016-03-22 20:52:03

标签: xcode swift xcode7 swift3

好的,所以我只是将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()
}

9 个答案:

答案 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)

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Functions.html

输入输出参数

默认情况下,函数参数是常量。尝试从该函数体内更改函数参数的值会导致编译时错误。这意味着您无法错误地更改参数的值。如果您希望函数修改参数的值,并且希望在函数调用结束后这些更改仍然存在,请将该参数定义为输入输出参数。

您可以通过将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()
    }
}

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