Swift如果让我们成功评估Optional(nil)

Mat*_*ros 5 cocoa cocoa-touch optional ios swift

我有一个名为Field的自定义对象.我基本上用它来定义表单中的单个字段.

class Field {

    var name: String
    var value: Any?

    // initializers here...
}
Run Code Online (Sandbox Code Playgroud)

当用户提交表单时,我验证每个Field对象以确保它们包含有效值.有些字段不是必需的,所以我有时会故意设置nil为这样的value属性:

field.value = nil
Run Code Online (Sandbox Code Playgroud)

当我使用if-let来确定字段是否为零时,这似乎会造成问题.

if let value = field.value {
    // The field has a value, ignore it...
} else {
    // Add field.name to the missing fields array. Later, show the
    // missing fields in a dialog.
}
Run Code Online (Sandbox Code Playgroud)

我在上面的if-else中设置了断点,field.value故意设置为nil时,它会通过if-let块,而不是else.但是,对于field.value我未初始化和未分配的字段,程序将转到else块.

我想打印出来field.value,并value在IF-让块内:

if let value = field.value {
    NSLog("field.value: \(field.value), value: \(value)")
}
Run Code Online (Sandbox Code Playgroud)

这就是我得到的:

field.value:可选(零),值:nil

所以我认为可能有选择性,未初始化是一回事而另一个是nil的价值.但即使在if-let中添加另一个也不会让编译器满意:

if let value = field.value {
    if value == nil { // Cannot invoke '==' with an argument list of type '(Any, NilLiteralConvertible)'
    }
}
Run Code Online (Sandbox Code Playgroud)

我该如何解决这个问题?我只是想检查一下是field.value不是nil.

Jes*_*per 3

我相信这是因为Any?允许任何值并且Optional.None被解释为另一个值,因为它Optional是一个枚举!

AnyObject?应该无法执行此操作,因为它只能包含Optional.Some([any class object]),而不允许使用Optional.Some(Optional)value 的情况Optional.None

这甚至让人感到非常困惑。重点是:尝试AnyObject?而不是Any?看看是否有效。


更重要的是,马特的评论之一提到他想要使用的原因Any是为了进行选择,该选择可以是用于文本输入的字段,也可以是用于选择核心数据对象的字段。

在这种情况下,Swifty 要做的事情是使用具有关联值的枚举,基本上与标记/区分联合相同。以下是声明、分配和使用此类枚举的方法:

enum DataSelection {
    case CoreDataObject(NSManagedObject)
    case StringField(String)
}

var selection : DataSelection?

selection = .CoreDataObject(someManagedObject)

if let sel = selection { // if there's a selection at all
    switch sel {
        case .CoreDataObject(let coreDataObj):
            // do what you will with coreDataObj
        case .StringField(let string):
            // do what you will with string
    }
}
Run Code Online (Sandbox Code Playgroud)

使用这样的枚举,无需担心哪些内容可能隐藏在其中Any?。有两个案例,并且有记录。当然,选择变量可以是可选的,无需担心。

  • 是的,因为语言似乎没有办法区分“Optional.None”是用作实际值还是标记可选“Any”中不存在值。 (2认同)