xcode 'var'参数已弃用,将在Swift 3中删除

y3bcpkx1  于 2023-03-31  发布在  Swift
关注(0)|答案(9)|浏览(190)

好吧,我刚刚更新了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()
}
6ojccjat

6ojccjat1#

从函数参数中删除Var的讨论在GitHub上的此提交中有完整的记录:Remove Var Parameters
在该文档中,你会发现人们经常混淆var参数和inout参数。var参数只是意味着参数在函数的上下文中是可变的,而inout参数在返回点的参数值将从函数复制到调用者的上下文中。
解决这个问题的正确方法是从参数中删除var并引入一个本地变量var。在例程的顶部将参数的值复制到该变量中。

ohfgkhjo

ohfgkhjo2#

你有没有试着分配给一个新的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()
}
lrpiutwd

lrpiutwd3#

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

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

egdjgwm84#

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

62lalag45#

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

}

hjqgdpho

hjqgdpho6#

我认为@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()
}
332nm8kg

332nm8kg7#

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的值存储在一个名为temporaryA的临时常量中,将b的值赋给a,然后将temporaryA赋给b来执行交换。
你可以使用两个Int类型的变量来调用swapTwoInts(:)函数来交换它们的值。请注意,当它们被传递给swapTwoInts(:)函数时,someInt和anotherInt的名称前面会有一个&号:

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的原始值被swapTwoInts(:)函数修改,即使它们最初是在函数外部定义的。

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

u0sqgete

u0sqgete8#

这里是另一个想法。我的用例是传递一个字符串数组以追加到它,为此数组必须可变地传入。我也不想在我的类中有状态。所以我创建了一个类来保存数组并传递它。根据你的用例,让一个类只保存一个变量可能看起来很愚蠢。

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
}
agxfikkp

agxfikkp9#

我认为你应该使用inout,遵循this discussion中给出的建议。
在上下文中,在您的示例中:

public func getQuestionList(var language: String)

应改为:

public func getQuestionList(language: inout String)

相关问题