展开选装件(快速操场)

时间:2019-01-14 21:20:21

标签: swift conditional-statements optional forced-unwrapping

对您来说,关于展开可选内容的简单问题。

我已阅读并看到了如下所示的多个展开示例

var strArray: [String]?
strArray = ["John", "Stacy", "Stephanie" ]

if let forSureNames = strArray{
   for name in forSureNames{
      print("\(name)")
   }
} else{
    print("Failed unwrapping")
}

但是,我的问题是if let forSureNames = strArray{ ...

在键入类似于C ++的语法(以及一些快速示例)时,请添加括号

if (let forSureNames = strArray){

给出错误代码:

'()' is not convertible to 'Bool'

error: MyPlayground.playground:13:4: error: expected expression in list of expressions
if(let forSureName = strArrays){
   ^
error: MyPlayground.playground:13:4: error: expected '{' after 'if' condition
if(let forSureName = strArrays){
   ^

任何人都可以帮助解释差异吗?

编辑 第一次我问堆栈溢出问题,反馈很棒。由于我很容易过渡,因此我尝试使用与C ++类似的编码样式。但是,你们很清楚这是不正确的方法。感谢您提供关于展开的新技术观点。干杯!

4 个答案:

答案 0 :(得分:1)

如您所知,()可用于包围表达式,并且对该表达式的求值没有影响,您在问“为什么我不能对{{1}做同样的事情}?对吧?

这是因为let forSureNames = strArray不是表达式。您解析此语句错误。 let forSureNames = strArray一词是let语句的一部分。

您正在将if let语句与C样式的if语句混淆,在if let之后,总是有一个表达式,其结果为ifBool根本不能那样工作。格式为:

if let

其中if let <identifier> = <expression> { } 必须计算为可选类型。因此,将expression放在()周围毫无意义。您可以将let <identifier> = <expression>放在()周围,因为 that 是一个表达式,但我不明白这一点。

答案 1 :(得分:0)

if (let forSureNames = strArray) {

...这正尝试使用可选绑定。可选绑定使您可以安全地解包一些可选的常量/变量,它们可以是nil。如果分配了该值,则其具有此展开的(非可选的)常数/变量将满足if语句。

但是,它不适用于括号,因为来自括号的值必须为Bool类型。可选绑定不会直接返回Bool值,它只是尝试分配常量/变量,并且隐式根据分配是否发生返回布尔值。

if (true) {...} // works
if (let value = optional) {...} // doesn't work

因此,您必须删除这些括号

if let forSureNames = strArray {...}

与其他语言不同,Swift中的条件不必放在括号内,建议不要使用它们。

答案 2 :(得分:0)

Swift与C ++有很大的不同,因此C ++语法不能在Swift中工作,您应该不会感到惊讶。

在Swift中,if语句有两种类型:带表达式的类型(if foo.bar)和进行模式匹配的类型(if let foo = barif case .some(let foo) = bar等)。

因为Swift支持带括号的表达式,所以if foo.bar的作用与if (foo.bar)相同:第一种情况的条件是foo.bar,第二种情况的条件是{{1 }}。换句话说,这里的括号是条件表达式的一部分,而不是(foo.bar)语句的一部分。这与C ++相反,在C ++中,括号是if语句的一部分。但是,在两种情况下,都可以根据需要添加任意多个括号:if尽管很傻,但在两种语言中都表面上是有效的。

回想一下,您可以在括号中包装任意表达式,但不能只在括号中包装任何内容。您不会用Swift或C ++编写if (((((((((foo.bar))))))))),因为您知道(if foo.bar)不是表达式。然后,同样适用于if。它也不是表达式,因此不能将其括在括号中。 let foo = bar很好,但是if let foo = bar不好。

在某些情况下,C ++支持类似的语法:

if (let foo = bar)

此语法声明if (auto foo = make_unique<int>(3)) { ... } else { ... } 并对其进行测试(使用其foo),然后适当地分支程序。由于条件是声明语句,而不是表达式,因此也不能用括号括起来:operator bool()是编译时错误,就像Swift中的if ((auto foo = make_unique<int>(3)))一样。

答案 3 :(得分:0)

  

任何人都可以帮助解释差异吗?

区别在于Swift不是C ++。尽管它们在许多方面都相似,但是它们具有不同的语法。语法(部分地)定义了语言的语法。

在C ++中,if语句是语法中the selection-statement production的一部分:

  

选择说明:

     
    

if ( 条件 ) 声明

         

if ( 条件 ) 声明 else 声明

         

switch ( 条件 ) 声明

  

因此,if语句周围的括号是if语句的一部分,而不是一部分。

在Swift中,if语句是语法中the if-statement production的唯一产物:

  

if语句if条件列表代码块else-clause opt

请注意, if语句的产生中没有直接括号。因此,如果要加上括号,它们必须成为 condition-list 产生的一部分。 Here's how condition-list is defined

  

条件列表→条件|条件,条件列表

     

条件→表达式|可用性条件|案例条件可选的绑定条件

因此,条件列表是一个或多个条件,以逗号分隔。如果点击 condition 中的四个替代项,您会发现 availability-condition 必须以令牌#availability开头, case- condition 必须以令牌case开头,而 optional-binding-condition 必须以令牌let或令牌var开头。这三个产生式中的任何一个都不能以括号标记开头。

可以以令牌(开头的 condition 的唯一产生是 expression 产生,而 expression 产生不能在令牌let之后有令牌(