为啥你可以在 Swift 中为可选类型分配非可选值?

Posted

技术标签:

【中文标题】为啥你可以在 Swift 中为可选类型分配非可选值?【英文标题】:Why can you assign non-optional values to optional types in Swift?为什么你可以在 Swift 中为可选类型分配非可选值? 【发布时间】:2015-02-17 20:31:38 【问题描述】:

为什么涉及 Swift 选项类型检查的赋值? 例如在,

 var foo : Int? = 0
 foo = foo!

富和富!没有相同的类型。难道你不需要包装解开的值来将它分配给一个可选类型吗?

【问题讨论】:

【参考方案1】:

这是可选项背后的语法糖的一部分。分配一个非可选值是如何你将它包装在可选类型中。

由于可选项指示值的存在或不存在,因此除了提供值之外,您无需执行任何特殊操作来指示值的存在。例如,在一个函数中:

func gimmeSomethingMaybe() -> String? 
    if arc4random_uniform(10) > 7 
        return "something"
     else 
        return nil
    

想象一下,如果每次你想从一个能够返回 nil 的函数中返回一个实数值,你就必须写 return Optional(value)。那会很快变老,对吧?可选项是该语言的一个重要特性——尽管它们实际上是由标准库实现的,但语法糖/自动包装可以避免使用它们变得乏味。


编辑:只是更深入一点......糖还有助于强制执行实际值不应该是可选的概念。例如:

let one = 1
one? // error (in Swift 1.2, allowed but meaningless in Swift 1.1)
"two"? // error (ditto)

您可以使用 Optional(one) 初始化程序创建一个可选的包装真实值,但这本身几乎没有语义意义,因此您几乎不需要这样做。

当某个值是否存在存在“神秘”时,选项应该发挥作用——也就是说,当程序的一部分是否接收到值(或没有值)取决于该部分未知的状态时程序。如果你知道你有一个真正的价值,那就没有什么神秘的......相反,你让未知在知道价值的代码和不知道的代码之间的边界上发挥作用——即函数/方法/property 定义将该值传递给某个地方。

【讨论】:

我的问题被正确标记为重复。除了一部分,我什么都懂。你能回答我来自here的问题的最后一段吗?【参考方案2】:

在阅读了 rickster 的答案后,我想出了一个简单的外行术语答案。对我来说,他的答案的全部要点是

由于可选项表示值的存在或不存在,因此您 不应该做任何特别的事情来表明存在 提供一个以外的值

一个可选项是一个枚举。其中有 2 个案例 a 或 b。

                                      String?
                                         |
                                An enum with 2 cases
                                         |                               
                                 a               b
                                 |               |
                                Set            notSet
                                 |               |
                        any value like "hi"     nil

因此,当您想分配给可选项时,您可以做任何事情。

说值是:

a:设置为“hi” b:没有设置,所以是nil c:它只是等于另一个枚举,即另一个可选

代码:

var str : String?
var anotherOptional : String?

str = nil // nil <-- this is like case b
str = "hi" // "hi" <-- this is like case a

str = anotherOptional // nil <-- this is like case c

anotherOptional = "hi again"
str = anotherOptional // "hi again" <-- this is like case c

【讨论】:

以上是关于为啥你可以在 Swift 中为可选类型分配非可选值?的主要内容,如果未能解决你的问题,请参考以下文章

Swift 中的可选值是啥?

Swift - 将 nil 核心数据字符串转换为可选值

用返回非可选值的计算属性覆盖返回可选值的计算属性

Swift:在运行时在非可选中检测到意外的 nil 值:强制转换为可选失败

检查 nil 的非可选值

Swift16-可选链式调用