Swift 可选项 - 在条件中绑定变量需要初始化程序

20

我刚开始学习Swift,正试图弄清Optional的概念。在Playground中有一小段代码给我报错"Variable binding in a condition requires an initializer"。请问有人能解释一下为什么会这样并告诉我如何修复吗?

我只想根据"score1"是否存在来打印"Yes"或"No"。以下是代码:

import Cocoa

class Person {
    var score1: Int? = 9

    func sum() {
        if let score1 {
            print("yes")
        } else {
            print("No")
        }
    }//end sum
 }// end person

 var objperson = person()
 objperson.sum()
6个回答

19

if let语句接受一个可选变量。如果它为nil,则执行else块或什么都不执行。如果它有值,则将该值分配给另一个非可选类型的变量。

因此,以下代码将输出score1的值或如果没有则输出"No":

if let score1Unwrapped = score1
{
    print(score1Unwrapped)

}

else
{
    print("No")
}

同样的意思,更简短的版本:

print(score1 ?? "No")
在您的情况下,如果您实际上没有使用可选变量中存储的值,您还可以检查该值是否为nil:
if score1 != nil {
...
}

谢谢LorenzSchaef - 我基本上得出了相同的结论。 - Harry
1
当不使用解包值时的另一个选项是:if let _ = score1 { ... } - Michael Behan

5

撰写

if let score1 {

没有意义。如果你想查看score是否有值,请使用

if score1 != nil {

或者

if let score = score1 {

最后一种情况将一个新的非可选常量score绑定到score1。这使得你可以在if语句中使用score


2
自从Swift 5.7版本以后,这是有效的。 - Fab1n

3

虽然现在是这样,但最初提出这个问题是在2015年,在Swift添加这个新语法之前。 - wyu

0

自问题首次发布以来(如评论中所述),该问题中的语法已成为有效的Swift。

在控制流程检查表中,可选绑定使用与声明相同的语法(使用letvar),尽管语义有些不同:表达式的类型必须Optional,如果值为nil,则该检查表将立即短路,如果不是nil,则该值将被隐式解包。

注意:支持解构。每个表达式都必须是Optional(以进行编译),如果任何值为nil,则检查表将短路。

由于在Swift中直接重用(通过重新声明)变量非常常见,因此可以在检查表中使用简写let foo(或var foo)代替let foo = foo(或var foo = foo)。


0
问题在于if let假设您想要创建一个带有某个值的常量score1。如果您只想检查它是否包含一个值,例如不是nil,则应该像下面这样做:
if score1! != nil {
     // println("yes")

所以你的完整代码应该是这样的:

class Person {
    var score1: Int? = 9

    func sum() {
        if score1 != nil {
            println("yes")
        }
        else {
            println("no")
        }
    }
}

var objperson = Person()
objperson.sum()

这不是在Swift中用于测试nil的习语。上面的答案,以“if let score1 = score { …”的形式,是正确的方法。请注意,取消包装的变量可以与包装的变量具有相同的名称,在Swift代码中也已成为常规做法。 - Vince O'Sullivan

-1

您可以使用以下方法对其进行解包:

import Cocoa

class Person {
    var score1: Int? = 9

    func sum() {
        print("\(score1 != nil ? "YES" : "NO")")
    }
 }

然后像这样调用:

 var objperson = Person()
 objperson.sum()

FYI - 这里没有解包。你只是检查它是否为 nil。这是一个完全有效的答案,除了错误地陈述你正在使用解包。我猜旧的 downvote(踩)是因为这个答案基本上重复了几个更早的答案,建议简单比较 score1nil - HangarRash

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接