-3

关于解包选项的简单问题。

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

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++ 的语法时(以及一些 swift 示例),添加括号

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

4 回答 4

1

如您所知,()可用于包围表达式,并且不会对该表达式的评估产生影响,而您在问“为什么我不能对 做同样的事情let forSureNames = strArray?” 对?

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

您将if let语句与 C 风格的 if 语句混淆,在 之后if,总是有一个表达式计算为Boolif let根本不是那样工作的。它采用以下形式:

if let <identifier> = <expression> { }

whereexpression必须评估为可选类型。因此,()四处走动let <identifier> = <expression>是没有意义的。你可以把它放在一边()strArray因为是一种表达方式,但我不明白这一点。

于 2019-01-14T21:50:57.153 回答
0
if (let forSureNames = strArray) {

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

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

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

所以,你必须删除这些括号

if let forSureNames = strArray {...}

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

于 2019-01-14T21:25:19.027 回答
0

Swift 与 C++ 有很大的不同,所以你不应该对 C++ 语法在 Swift 中不起作用感到惊讶。

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

因为 Swift 支持带括号的表达式,if foo.bar其工作方式与if (foo.bar): 在第一种情况下,条件是foo.bar,而在第二种情况下,条件是(foo.bar)。换句话说,这里的括号是条件表达式的一部分,而不是if语句的一部分。这与 C++ 形成对比,其中括号是if语句的一部分。但是,在这两种情况下,您都可以根据需要添加任意数量的括号:if (((((((((foo.bar)))))))))虽然很傻,但在两种语言中表面上都是有效的。

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

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

if (auto foo = make_unique<int>(3)) { ... } else { ... }

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

于 2019-01-14T21:51:39.130 回答
0

任何人都可以帮助解释其中的区别吗?

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

在 C++ 中,if语句是语法选择语句产生的一部分:

选择声明:

if ( 条件 ) 语句

if ( 条件 ) 语句 else 语句

switch ( 条件 ) 语句

所以语句条件周围的括号是if语句的一部分if,而不是条件的一部分。

在 Swift 中,语句是语法if 语句产生if式的唯一产生式:

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

请注意,在if 语句的产生式中没有直接的括号。所以如果有括号,它们必须是条件列表产生的一部分。以下是条件列表的定义方式

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

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

所以条件列表是一个或多个条件,用逗号分隔。如果单击condition中的四个选项中的每一个,您会发现availability-condition必须以 token 开头#availabilitycase-condition必须以 token 开头case,而optional-binding-condition必须以 tokenlet或 token开头var. 这三个产品都不能以括号标记开头。

唯一可以以记号开头的条件(产生式是表达式产生式,表达式产生式不能在记号let之后有记号(

于 2019-01-14T22:15:16.453 回答