gpt4 book ai didi

swift - 使用隐式解包选项但测试 nil 与可选绑定(bind)是否存在技术缺点?

转载 作者:搜寻专家 更新时间:2023-10-31 21:50:38 24 4
gpt4 key购买 nike

好吧,所以我知道在 Swift 中使用可选值的正常方法是通过可选绑定(bind)来解包它们,就像这样......

let stringA:String? = nil // (or "ABC")

if let unwrappedStringA = stringA
{
let x:String = unwrappedStringA
}

但我也看到了以下使用隐式解包选项的方式,我个人认为它看起来更干净,因为它不仅不需要额外的变量,而且它“读起来”更好,更像英语(即 '如果这不是零,那么...') 并且可读性是 Swift 的核心原则之一(尤其是在即将到来的 Swift 3.0 中)。

let stringA:String! = nil // (or "ABC")

if stringA != nil
{
let x:String = stringA
}

然而,对于后者,Swift 的“纯粹主义者”将其称为“代码味道”并坚持认为它是“糟糕、糟糕、糟糕!!”……但他们从不解释原因!那么……为什么这么糟糕?

注意:是的,我知道可选链接和其他不能与隐式解包可选一起使用的功能,它们都是非常酷的功能,但我特别询问测试的技术缺点针对 nil 与可选绑定(bind)的隐式解包选项。

我希望的是可量化的技术原因,说明一个比另一个更好(即编译器优化、更好的安全检查、性能等)。换句话说,不仅仅是“嘿,因为那是不是“swift ”的方式来做到这一点!希望这是有道理的。

更新

实际上,我只是找到了一种方法来解决我的一个问题(至少是表面上的),即必须创建一个新变量来保存未包装的变量。这里的技巧是因为展开的变量实际上与可选变量本身在不同的范围内,您可以使用完全相同的名称。

此外,括号内还有另一个作用域,它也可以有一个名为 stringA 的变量。这意味着您现在可以拥有三个“stringA”变量(但并不意味着您应该!)...

  1. 可选的
  2. 未包装的可选
  3. 括号内的一个新的局部变量

这是一段疯狂的代码,展示了这一点......

let stringA:String? = nil // (or "ABC") // First stringA variable

if let stringA = stringA
{
let x:String = stringA // <- This stringA is the unwrapped optional (the second stringA)

// Now we're just getting crazy (and smelly!)
let stringA = stringA + stringA // <- This is yet another stringA (third one!)
let y:String = stringA
}

再说一次,我不会宽恕这一点!!我只是展示了一些代码,其他人可能从有启发性的角度来看会觉得有趣。我确实做到了!

最佳答案

确实有一个简单的原因,它就是您列出的原因之一:“更好的安全检查”。可选绑定(bind)使编译器知道解包的范围,而程序员有责任跟踪您何时检查或未检查隐式解包的可选项是否为 nil

带有可选绑定(bind):

let stringA:String? = nil // (or "ABC")

if let unwrappedStringA = stringA
{
let x:String = unwrappedStringA
}

accidentallyAttemptingToUse(stringA) // Compiler error! I see my mistake.

使用隐式展开:

let stringA:String! = nil // (or "ABC")

if(stringA != nil)
{
let x:String = stringA
}

accidentallyAttemptingToUse(stringA) // Runtime crash I might find in testing. Yuck.

IUO 有哪些用途?

那么,为什么要隐式解包可选值呢?它们的存在基本上是为了一个目的:肯定会有值的属性,但要在 init 之后不久才会有,因此它们必须是可选的。通常 @IBOutlet 属于这一类:您可以相信它们有一个值,并且您不想一直打开它们,但它们不是在 init< 时分配的,因此您必须将它们设为可选。 就是隐式展开的可选值的用途。

展开到同名变量

您的更新暂时建议将可选项展开为具有相同名称的变量,这实际上是 优秀 Swift 风格,并且很早就被 Apple 使用并经常使用。当您解包到同名变量时,代码更容易阅读,因为您可以跟踪更少(更好)的名称。绝对接受这一点!

let stringA:String? = nil // (or "ABC")

if let stringA = stringA
{
let x:String = stringA // Of *course* this is still named `stringA`;
// it's representing the same concept, after all.
}

关于swift - 使用隐式解包选项但测试 nil 与可选绑定(bind)是否存在技术缺点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38341198/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com