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
变量。它应该像在范围之前声明变量一样简单,但我无法在没有guard
或let
关键字的情况下找到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
语句是布尔上下文而不是变量赋值。
有关如何解决此问题的任何想法?
答案 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
}