Swift如果let评估成功on可选(nil) [英] Swift if let evaluates successfully on Optional(nil)

查看:212
本文介绍了Swift如果let评估成功on可选(nil)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a custom object called Field. I basically use it to define a single field in a form.

class Field {

    var name: String
    var value: Any?

    // initializers here...
}

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

When the user submits the form, I validate each of the Field objects to make sure they contain valid values. Some fields aren't required so I sometimes deliberately set nil to the value property like this:

field.value = nil

当我使用if-let确定字段是否为nil时,这似乎会出现问题。

This seems to pose a problem when I use an if-let to determine whether a field is nil or not.

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.
}



在上述if-else和中设置断点c $ c> field.value 已被故意设置为nil,它通过if-let块而不是else。但是,对于 field.value 我未初始化和未分配,程序转到else块。

I set breakpoints in the above if-else and when field.value has been deliberately set to nil, it goes through the if-let block, not the else. However, for the fields whose field.value I left uninitialized and unassigned, the program goes to the else block.

在if-let块内的 field.value

I tried printing out field.value and value inside the if-let block:

if let value = field.value {
    NSLog("field.value: \(field.value), value: \(value)")
}

这是我得到的:


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

field.value: Optional(nil), value: nil

也许有可选,它是一个事情是未初始化和另一个具有值nil。但是如果在if-let内部添加另一个if不允许编译器满意,那么甚至添加另一个:

So I thought that maybe with optionals, it's one thing to be uninitialized and another to have the value of nil. But even adding another if inside the if-let won't make the compiler happy:

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

如何解决这个问题?我只想检查 field.value 是否 nil

How do I get around this? I just want to check if the field.value is nil.

推荐答案

我相信这是因为任何?允许任何值和 Optional.None 被解释为只是另一个值,因为可选是枚举!

I believe this is because Any? allows any value and Optional.None is being interpreted as just another value, since Optional is an enum!

AnyObject?应该不能这样做,因为它只能包含 Optional.Some([any class object])对于 Optional.Some(可选)使用值 Optional.None 的情况。

AnyObject? should be unable to do this since it only can contain Optional.Some([any class object]), which does not allow for the case Optional.Some(Optional) with the value Optional.None.

这甚至令人困惑甚至谈论。重点是:尝试 AnyObject?而不是任何?,看看是否工作。

This is deeply confusing to even talk about. The point is: try AnyObject? instead of Any? and see if that works.

更重要的是,Matt的一篇评论提到了他想使用 Any 用于一个选择,可以是文本输入的字段或用于选择Core Data对象的字段。

More to the point, one of Matt's comment mentions that the reason he wants to use Any is for a selection that could be either a field for text input or a field intended to select a Core Data object.

在这种情况下,Swifty要做的是使用枚举与相关值,基本上与标记/歧视的联盟。以下是如何声明,分配和使用这样的枚举:

The Swifty thing to do in this case is to use an enum with associated values, basically the same thing as a tagged/discriminated union. Here's how to declare, assign and use such an enum:

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
    }
}

使用这样的枚举,不必担心哪些内容可能隐藏在任何?。有两种情况,他们被记录。当然,选择变量可以是可选的,没有任何后顾之忧。

Using an enum like this, there's no need to worry about which things could be hiding inside that Any?. There are two cases and they are documented. And of course, the selection variable can be an optional without any worries.

这篇关于Swift如果let评估成功on可选(nil)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆