Iva*_*n X 34 macos optional ios swift
可选项的全部原因是为了防止因命中分配给nil/null/none的变量而导致的运行时崩溃.因此,变量不能为零; 相反,它们可以包含在一个Optional类型中,该类型将它们表示为Some或None,并解包以获取Some的具体内容,或者为nil.
但是如果你用它们!或者用Implicitly Unwrapped Optionals 打开它们,你只需要引入运行时崩溃的可能性,因为你是一个不完美的编码器.如果你使用它if let来安全地打开它们,你可以避免崩溃,但是你被困在if let语句的范围内以使用Some中的值,你仍然需要处理潜在的nil情况.如果使用?为了调用方法暂时解包,它将在完成后重新包装,引入多层次可选包装的混乱可能性.
所以:在我看来,要做的是避免选项,除非必要时(例如,当调用返回它们的框架方法时).但是,如果我不使用选项,那意味着我的对象引用必须是非零的,我无法弄清楚如何处理由于某种原因不应该存在或者不存在的情况,分配给对象引用的值.
我的问题是:我如何避免需要零?看起来它需要一种不同的编程方法.(或者我应该只使用选项,如果这就是我正在做的,那么除了像其他语言那样简单地对对象引用进行空分配外,它有什么用?)
我知道这可能是一个主观问题,但我还应该问其他问题呢?我不是想哄骗或激起辩论,我真的很想知道正确的方法是什么,因为我写了更多的Swift代码.
Air*_*ity 84
你是对的,选择权可能是一种痛苦,这就是为什么你不应该过度使用它们.但它们不仅仅是在使用框架时必须处理的事情.它们是一个非常常见问题的解决方案:如何处理一个返回结果可能正常或可能不正常的调用.
例如,拿走Array.first会员.这是一个方便的实用程序,它为您提供数组的第一个元素.a.first当你可以打电话时,为什么能够打电话是有用的a[0]?因为在运行时,数组可能为空,在这种情况下a[0]会爆炸.当然你可以a.count事先检查- 但是再次检查
一个.你可能会忘记,
和
湾 这导致相当丑陋的代码.
Array.first通过返回可选项来处理此问题.因此,您必须先打开可选项,然后才能使用作为数组第一个元素的值.
现在,关于仅在块内部存在的展开值的问题if let.想象一下并行代码,检查数组计数.会是一样的吧?
if a.count > 0 {
// use a[0]
}
// outside the block, no guarantee
// a[0] is valid
if let firstElement = a.first {
// use firstElement
}
// outside the block, you _can't_
// use firstElement
Run Code Online (Sandbox Code Playgroud)
当然,如果计数为零,您可以执行类似于从函数执行早期返回的操作.这有效,但有点容易出错 - 如果你忘记这样做,或者把它放在一个没有碰巧运行的条件语句中呢?基本上你也可以这样做array.first:在函数的早期检查计数,然后再做array.first!.但这!对你来说就是一个信号 - 要注意,你正在做一些危险的事情,如果你的代码不完全正确,你会很抱歉.
可选项也有助于使替代品略微漂亮.假设您想要在数组为空时默认值.而不是这个:
array.count > 0 ? a[0] : somedefault
Run Code Online (Sandbox Code Playgroud)
你可以这样写:
array.first ?? somedefault
Run Code Online (Sandbox Code Playgroud)
这在几个方面更好.它将重要的事情放在前面:你想要的值是表达式的开始,然后是默认值.与三元表达式不同,后者首先使用检查表达式,然后是您实际需要的值,然后是默认值.它也更加万无一失 - 更容易避免输入拼写错误,也不可能导致错误导致运行时爆炸.
再举一个例子:find功能.这将检查值是否在集合中并返回其位置的索引.但该值可能不会出现在集合中.其他语言可以通过返回结束索引来处理这个问题(它不指向一个值,而是指向一个超过最后一个值的值).这就是所谓的"哨兵"值 - 看起来像常规结果的值,但实际上具有特殊含义.与前面的示例一样,在使用结果之前,您必须检查结果是否与结束索引不同.但你必须知道这样做.您必须查找文档find并确认其工作原理.
通过find返回一个可选项,它很自然,当你理解了可选的习语时,要意识到它的原因是因为结果可能因为显而易见的原因而无效.上面提到的所有关于安全性的事情也适用 - 你不能不小心忘记,并将结果用作索引,因为你必须首先解开它.
也就是说,你可以过度使用选项,因为它们是必须检查的负担.这就是数组下标不返回选项的原因 - 它必须经常检查和解包它们会造成很多麻烦,特别是当你知道你使用的索引是有效的时候(例如,你在人们将!不断使用的for循环遍历数组的有效索引范围,从而使代码混乱而没有任何好处.但是,添加了第一个和最后一个辅助方法,以涵盖人们想要快速执行操作而不必先检查数组大小但希望安全地执行操作的常见情况.
(另一方面,Swift Dictionaries预计会通过无效的下标定期访问,这就是为什么他们的[key]方法返回一个可选的)
更好的是,如果可以完全避免失败的可能性.例如,当filter匹配没有元素时,它不返回可nil选项.它返回一个空数组.你可能会说,"显然它会".但是你会惊讶地发现,当你真正应该返回一个空数时,你会看到有人像一个数组一样选择返回值.所以你完全正确地说你应该避免选择,除非它们是必要的 - 这只是一个必要的手段的问题.在上面的例子中,我会说它们是必要的,并且是替代方案的更好解决方案.
zou*_*oul 13
或者我应该只使用选项,如果这就是我正在做的事情,那么除了像其他语言一样对对象引用进行空赋值之外,它有什么用呢?
如果你的计算可能需要返回一个"特殊"值,那么是的,在Swift中你应该使用选项.它们比可空类型更好,因为它们是明确的.很容易错过一个指针可能的情况nil,它更难(但完全可能)搞砸了选项.
如果你使用"if let"来安全地打开它们,你可以避免崩溃,但是你被困在"if let"语句的范围内来处理这个值,你仍然需要处理潜在的nil情况.
这是一个功能.我的意思是,这是一个可选类型的全部要点:你必须处理两种情况(nil和非nil),你必须明确它.
有关类似概念的示例,请参阅Haskell的Maybe类型和monad.Maybe类型与可选类型完全等效,Maybe monad使得使用这些可选值"链接"操作变得非常容易,而无需一直手动检查空值.
| 归档时间: |
|
| 查看次数: |
6301 次 |
| 最近记录: |