解包选项(Swift 游乐场)
Unwrapping Optionals (Swift Playground)
关于展开可选值的简单问题。
我已经阅读并看到了像下面这样展开的多个示例
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){
^
谁能帮忙解释一下区别?
编辑
我第一次问有关 Stack overflow 的问题,反馈很棒。由于我对轻松过渡很熟悉,因此我尝试使用与 C++ 类似的编码风格。但是,你们明确表示这是一种不正确的方法。感谢您对展开的新的技术观点。干杯!
if (let forSureNames = strArray) {
...这是在尝试使用可选绑定。可选绑定允许您安全地解包一些可选的 constant/variable,它可以是 nil
。如果分配了此值,则它满足 if
具有此展开(非可选)constant/variable.
的语句
但是,它不适用于括号,因为来自括号的值必须是 Bool
类型。可选绑定不会直接 return 一个 Bool
值,它只是尝试将 constant/variable 和 隐式地 return 分配给一个布尔值基于分配是否发生。
if (true) {...} // works
if (let value = optional) {...} // doesn't work
因此,您必须删除这些括号
if let forSureNames = strArray {...}
与其他语言不同,Swift 中的条件不必放在括号内,如果不需要,建议不要使用它们。
如你所知,()
可以用来包围一个表达式,它不会影响该表达式的计算,你问的是 "why can't I do the same to let forSureNames = strArray
?" 对吗?
这是因为 let forSureNames = strArray
不是表达式。您错误地解析了此语句。单词 let
是 if let
语句的一部分。
您将 if let
语句与 C 风格的 if 语句混淆了,在 if
之后总是有一个计算结果为 Bool
的表达式。 if let
那样根本行不通。它采用以下形式:
if let <identifier> = <expression> { }
其中 expression
必须评估为可选类型。因此,将 ()
放在 let <identifier> = <expression>
周围没有什么意义。你可以把 ()
放在 strArray
周围,因为 that 是一个表达式,但我不明白那有什么意义。
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)))))))))
,虽然很愚蠢,但在两种语言中表面上都是有效的。
回想一下,您可以将任意表达式括在括号中,但不能只将任何内容括在括号中。您不会在 Swift 或 C++ 中编写 (if foo.bar)
,因为您知道 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)))
是一个编译时错误,就像Swift中的if (let foo = bar)
一样。
Can anyone help explain the difference?
区别在于Swift不是C++。尽管它们在许多方面相似,但它们具有不同的语法。文法(部分)定义了语言的句法。
在 C++ 中,if
语句是语法中 the selection-statement production 的一部分:
selection-statement:
if
(
condition )
statement
if
(
condition )
statement else
statement
switch
(
condition )
statement
因此 if
语句的条件括号是 if
语句的一部分,而 不是 条件的一部分。
在Swift中,if
语句是语法中the if-statement production的唯一产生式:
if-statement → if
condition-list code-block else-clauseopt
请注意,if 语句 的产生式中没有括号。因此,如果要有括号,它们必须是 condition-list 产生式的一部分。 Here's how condition-list is defined:
condition-list → condition | condition ,
condition-list
condition → expression | availability-condition | case-condition | optional-binding-condition
所以一个条件列表是一个或多个条件,用逗号分隔。如果您单击 condition 中的四个选项中的每一个,您会发现 availability-condition 必须以标记 #availability
开头,case-condition 必须以标记 case
开头,并且 optional-binding-condition 必须以标记 [=28] 开头=] 或令牌 var
。 None 这三个作品可以以括号标记开头。
唯一可以以标记 (
开始的 condition 的产生式是 expression 产生式,并且 expression production 在 token (
.
之后不能有 token let
关于展开可选值的简单问题。
我已经阅读并看到了像下面这样展开的多个示例
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){
^
谁能帮忙解释一下区别?
编辑 我第一次问有关 Stack overflow 的问题,反馈很棒。由于我对轻松过渡很熟悉,因此我尝试使用与 C++ 类似的编码风格。但是,你们明确表示这是一种不正确的方法。感谢您对展开的新的技术观点。干杯!
if (let forSureNames = strArray) {
...这是在尝试使用可选绑定。可选绑定允许您安全地解包一些可选的 constant/variable,它可以是 nil
。如果分配了此值,则它满足 if
具有此展开(非可选)constant/variable.
但是,它不适用于括号,因为来自括号的值必须是 Bool
类型。可选绑定不会直接 return 一个 Bool
值,它只是尝试将 constant/variable 和 隐式地 return 分配给一个布尔值基于分配是否发生。
if (true) {...} // works
if (let value = optional) {...} // doesn't work
因此,您必须删除这些括号
if let forSureNames = strArray {...}
与其他语言不同,Swift 中的条件不必放在括号内,如果不需要,建议不要使用它们。
如你所知,()
可以用来包围一个表达式,它不会影响该表达式的计算,你问的是 "why can't I do the same to let forSureNames = strArray
?" 对吗?
这是因为 let forSureNames = strArray
不是表达式。您错误地解析了此语句。单词 let
是 if let
语句的一部分。
您将 if let
语句与 C 风格的 if 语句混淆了,在 if
之后总是有一个计算结果为 Bool
的表达式。 if let
那样根本行不通。它采用以下形式:
if let <identifier> = <expression> { }
其中 expression
必须评估为可选类型。因此,将 ()
放在 let <identifier> = <expression>
周围没有什么意义。你可以把 ()
放在 strArray
周围,因为 that 是一个表达式,但我不明白那有什么意义。
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)))))))))
,虽然很愚蠢,但在两种语言中表面上都是有效的。
回想一下,您可以将任意表达式括在括号中,但不能只将任何内容括在括号中。您不会在 Swift 或 C++ 中编写 (if foo.bar)
,因为您知道 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)))
是一个编译时错误,就像Swift中的if (let foo = bar)
一样。
Can anyone help explain the difference?
区别在于Swift不是C++。尽管它们在许多方面相似,但它们具有不同的语法。文法(部分)定义了语言的句法。
在 C++ 中,if
语句是语法中 the selection-statement production 的一部分:
selection-statement:
if
(
condition)
statement
if
(
condition)
statementelse
statement
switch
(
condition)
statement
因此 if
语句的条件括号是 if
语句的一部分,而 不是 条件的一部分。
在Swift中,if
语句是语法中the if-statement production的唯一产生式:
if-statement →
if
condition-list code-block else-clauseopt
请注意,if 语句 的产生式中没有括号。因此,如果要有括号,它们必须是 condition-list 产生式的一部分。 Here's how condition-list is defined:
condition-list → condition | condition
,
condition-listcondition → expression | availability-condition | case-condition | optional-binding-condition
所以一个条件列表是一个或多个条件,用逗号分隔。如果您单击 condition 中的四个选项中的每一个,您会发现 availability-condition 必须以标记 #availability
开头,case-condition 必须以标记 case
开头,并且 optional-binding-condition 必须以标记 [=28] 开头=] 或令牌 var
。 None 这三个作品可以以括号标记开头。
唯一可以以标记 (
开始的 condition 的产生式是 expression 产生式,并且 expression production 在 token (
.
let