如何在Swift 2

时间:2015-12-18 21:32:37

标签: variables swift2

guard关键字非常棒,自从Swift 2推出以来,我一直在使用它。我能够在许多场景中成功使用它,包括这一个:

for viewController in self.navigationController!.viewControllers {
    guard let myCustomVC = viewController as? MyCustomViewController else {continue}

    myCustomVC.doWhatItHasToDo()
    break
}

像魅力一样工作。迭代当前viewControllers中的所有navigationController,直到找到我想要的那个。

问题是:现在我需要更新上面的代码,以便在myCustomVC范围之外重用for..in变量。它应该像在范围之前声明变量一样简单,但我无法在没有guardlet关键字的情况下找到var变量赋值的方法。

以下假设代码展示了我想要实现的目标,但Swift不会让我这样做:

var myCustomVC: MyCustomViewController
for viewController in self.navigationController!.viewControllers {
    guard myCustomVC = viewController as? MyCustomViewController else {continue}

    myCustomVC.doWhatItHasToDo()
    break
}

// Now myCustomVC is available outside the for...in scope
myCustomVC.doWhatever()

Xcode建议使用==而不是=,因为它期望guard语句是布尔上下文而不是变量赋值。

Xcode error

有关如何解决此问题的任何想法?

2 个答案:

答案 0 :(得分:1)

请原谅我没有回答你的问题。我不认为你问的是可能的。但我有另一种选择。

好像你是一遍又一遍地手动编写filter方法。我建议只使用filter来找到你想要的元素。如果有多个匹配项,请使用first获取第一个匹配项。例如,下面我从列表中选择第一个偶数:

let myArray = [0,1,3,5,7,4,6,10,11]
let myNum = myArray.filter { $0 % 2 == 0 }.first

我不知道用于谓词的确切语法,但类似于以下内容

let myCustomVC = self.navigationController!.viewControllers.filter {
    $0 is MyCustomViewController }.first

// myCustomVC will be an optional because first returns an optional
if let myCustomVC = myCustomVC {
    myCustomVC.doWhatItHasToDo()
    myCustomVC.doWhatever()
}

或者,如果您要对与谓词匹配的每个元素执行操作,请使用foreach

    let myCustomVC = self.navigationController!.viewControllers.filter {
    $0 is MyCustomViewController }.foreach { // action // }

答案 1 :(得分:0)

我继续考虑你的问题。可以做你最初提出的问题,但我提出的解决方案有点复杂。基本上它涉及定义类型Any -> Bool的闭包,您可以在guard语句中使用它。这是一个完整的例子。也许如果这很有用,你可以清理它。假设你已经在某处定义了谓词闭包,那么实际的for循环并不错。

class MyClass {}

var myCollection = [Any]()
// add sample elements 
myCollection.append("hello")
myCollection.append(MyClass())

// declare the variable to receive the "found" element
var myElement:MyClass? = nil

// define our predicate to use in guard statement
let myPredicate:Any->Bool = { obj in
    if let obj = obj as? MyClass {
        myElement = obj
        return true
    }
    return false
}

for v in myCollection {
    guard myPredicate(v)
    else {continue}

   // do something with v
}

if let myElement = myElement {
    print(myElement)
}

更新:一个更简单的例子(它仍然需要让)

for v in myCollection {
    guard let myObj = v as? MyClass else {continue}
    myElement = myObj
}