与逻辑AND运算符&&一起使用Swift


93

我们知道我们可以使用一条if let语句作为简写形式来检查可选的nil,然后将其解包。

但是,我想使用逻辑AND运算符将其与另一个表达式组合&&

因此,例如,在这里,我进行可选的链接来解包,也可以选择将我的rootViewController下放到tabBarController。但是,与其嵌套if语句,不如将它们组合在一起。

if let tabBarController = window!.rootViewController as? UITabBarController {
    if tabBarController.viewControllers.count > 0 {
        println("do stuff")
     }
 }

联合捐赠:

if let tabBarController = window!.rootViewController as? UITabBarController &&
    tabBarController.viewControllers.count > 0 {
        println("do stuff")
     }
}

上面给出了编译错误使用未解析的标识符'tabBarController'

简化:

if let tabBarController = window!.rootViewController as? UITabBarController && true {
   println("do stuff")
}

这给出了编译错误。条件绑定中的绑定值必须是Optional类型。尝试了各种语法变化之后,每种变化都会产生不同的编译器错误。我还没有找到顺序和括号的组合。

因此,问题是,是否可能?如果可以,正确的语法是什么?

请注意,我想与做这个if说法不是一个switch语句或三元?运营商。


在问题中提供错误消息总是一个好主意。
zaph 2014年

对于喜欢尝试这种方法的人来说,更简单的说法是:var foo : Int? = 10; if let bar = foo { if bar == 10 { println("Great success!") }}
DarkDust 2014年

使用时的错误消息if let bar = foo && bar == 10Use of unresolved identifier "bar"bar当然是第二个)。
DarkDust 2014年

请注意,我能够使用Objective C的firstObject简化上述示例,如下所示:如果让navigationController = tabBarController.viewControllers.bridgeToObjectiveC()。firstObject如?UINavigationController {
Max MacLeod 2014年

1
1. bridgeToObjectiveC已在Beta 5中消失(并且很可能从未打算用于一般用途)。2. 无论如何first,Swift的内置Array类型都有一个方法。
rickster 2014年

Answers:


143

从Swift 1.2开始,这已经成为可能。在雨燕1.2与6.3的Xcode beta版笔记状态:

使用 if let进行更强大的可选包装-现在,if let构造可以立即打开多个可选包装,并包括中间的布尔条件。这使您可以表达条件控制流而无需不必要的嵌套。

使用上面的语句,语法将是:

if let tabBarController = window!.rootViewController as? UITabBarController where tabBarController.viewControllers.count > 0 {
        println("do stuff")
}

这使用该where子句。

另一个示例,这次转换AnyObjectInt,解开可选的,并检查解开的可选是否满足条件:

if let w = width as? Int where w < 500
{
    println("success!")
}

对于现在使用Swift 3的用户,“ where”已被逗号替换。因此,等效项为:

if let w = width as? Int, w < 500
{
    println("success!")
}

2
这应该是选择的答案。
Francis.Beauchamp

是的,因为现在已更改。布莱恩的答案当时是正确的
麦克劳德·麦克劳德

58

Swift 3 Max MacLeod的示例如下所示:

if let tabBarController = window!.rootViewController as? UITabBarController, tabBarController.viewControllers.count > 0 {
    println("do stuff")
}

where被替换,


10
因此,&&是|&有什么用。?
jeet.chanchawat 16/09/29

9
在这种情况下,@ jeet.chanchawat逻辑或没有意义。if let仅当成功解开了可选变量并将其分配给新变量名称后,才能继续执行。如果您说的是,OR <something else>那么您可以轻松绕过该产品的整个用途if let。对于逻辑或,只需执行一个法线,if并在主体内部处理以下事实:第一个对象在该点仍然是可选的(未展开)。
jhabbott

37

马克斯的答案是正确的,也是做到这一点的一种方法。请注意,以这种方式编写时:

if let a = someOptional where someBool { }

someOptional表达式将首先被解析。如果失败,则不对someBool表达式进行求值(如您所愿,进行短路求值)。

如果您想以其他方式编写此代码,可以这样:

if someBool, let a = someOptional { }

在这种情况下,someBool将首先对someOptional表达式求值,并且仅当其求值为true时才对表达式求值。


5

Swift 4,我将使用

let i = navigationController?.viewControllers.index(of: self)
if let index = i, index > 0, let parent = navigationController?.viewControllers[index-1] {
    // access parent
}

4

这不可能。

Swift语法

IF语句的语法

if语句→ if条件代码块else子句elseoptcla

如果条件→表达式| 宣言

else-clause→ else代码块| 否则 if陈述

if语句中任何条件的值都必须具有符合BooleanType协议的类型。条件也可以是可选绑定声明,如可选绑定中所述

如果条件必须是表达式声明。您不能同时拥有表达式和声明。

let foo = bar是一个声明,它的计算结果不符合BooleanType。它声明一个常量/变量foo

您最初的解决方案已经足够好,与条件组合起来可读性更强。


但可以肯定的是,“ if let”(有效的Swift语法)既是表达式又是声明?
Max MacLeod 2014年

@MaxMacLeod let foo = bar是声明而不是表达式。你做不到let boolValue = (let foo = bar)
Bryan Chen

好的,但是引用第11页的Swift指南,示例是:if let name = optionalName。optionalName必须是一个表达式,如果optionalName不是可选的,则其值为true。然后,该语句的第二部分将展开,其中将未包装的可选内容分配给name。因此,问题是,如果“ optionalName不是可选的”是一个表达式,则可以使用逻辑AND对其进行扩展。顺便说一句,我认为您可能是正确的,因为它无法完成。
Max MacLeod 2014年

-1

我认为您最初的主张还不错。(更麻烦的)替代方法是:

if ((window!.rootViewController as? UITabBarController)?.viewControllers.count ?? 0) > 0 {
    println("do stuff")
}

1
但您需要编写代码才能tabBarController再次投放
Bryan Chen
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.