【问题标题】:use of let in optional value along with if在可选值中使用 let 和 if
【发布时间】:2014-06-12 17:21:08
【问题描述】:

从 Apple 发布的 Swift 书中,我们可以通过放置 ?像

这样的变量
var optionalString: String? = "Hello"
optionalString == nil

还写道:“您可以使用 if 和 let 一起处理可能丢失的值。”

var optionalName: String? = "John Appleseed"
var greeting = "Hello!"
if let name = optionalName {
   greeting = "Hello, \(name)"
}

上面写的代码用来检查可选值是否为nil,如果 optionalName 为nil,它就不会进去。

但不使用 let like 也可以做到这一点

if optionalName {
     greeting = "Hello, \(optionalName!)"
}

为什么书中建议使用 let?

【问题讨论】:

  • 我一直在想同样的事情。虽然使用if let 避免了必须解开(可能多次)if 块中的值,但避免(1)必须包含额外的语法和(2)提出一个新变量似乎仍然更短您的可选名称,根据我的经验,这只是将firstName 变成theFirstName 缺乏创造力。
  • 你被字符串插值接受可选项的能力所迷惑。如果在该字符串之外使用了optionalName,则必须使用optionalName!.useMeSomehow() 显式解包它。用 let 绑定它,可以节省你在块内的那一步。
  • 你错过了'!'在您的第二个代码示例中。应为:greeting = "Hello, (optionalName!)"
  • 让返回一个布尔值...所以只有在选项检查出时才进入块...它是糖

标签: swift


【解决方案1】:

您的第二个代码 sn-p 在功能上等同于书中的那个。但是,本书建议使用let 来避免多次展开可选值。

由于您正在检查 optionalName 是否为空,因此可以安全地假设您计划在条件块中使用它。当你这样做时,Swift 需要再次从 optionalName 解包可选值,因为该变量仍然是可选的。

当您在let 声明中将optionalName 分配给name 时,您返回的name 常量不是可选的。这样可以节省您在 if 语句中的展开。

【讨论】:

  • 从你的回答中我得出的结论是功能方面它总是一样的。但是使用 let 的执行方式会很快,因为它只需要解包一次。
  • 如果我使用可选字符串或常量字符串也会影响执行时间吗?
  • @WildFire 这是正确的。展开对象一次的想法是节省时间 - 肯定是微优化,但它可能有助于紧密循环,甚至可能提高可读性。
  • 在这里不同意(只是使用看起来像我不同意的词(:)-我会想象一些非常小的优化会消除这样做的需要(假设幂等性),所以我认为它是真的更多关于范式和糖......
  • @GradyPlayer:这在单线程场景中是一个微不足道的优化,但我不确定展开非常量可选项在实践中是否可以证明是幂等的,因为多个线程可能可以访问它。
【解决方案2】:

您的困惑是因为您使用 println 来显示 optionalName,而 println 足够聪明,可以处理可选值并在必要时解开它们。如果您使用假设相似的代码:

if optionalName {
    greeting = "Hello, " + optionalName
}

你会因为不能连接一个字符串和一个字符串而得到一个错误?你有三种方法来解决这个问题

首先,您可以在检查后使用条件解包,但这效率低下,因为如果您多次引用 optionalName,因为您每次都必须解包。

if optionalName {
    greeting = "Hello, " + optionalName?
}

您可以通过使用强制展开来改进这一点,因为您已经完成了测试并且知道 optionalName 永远不能为 nil。如果您多次引用 optionalName,这仍然是低效的,因为每次都必须进行解包。

if optionalName {
    greeting = "Hello, " + optionalName!
}

最后,您可以使用 if let 语法同时测试和解包。 Name 可以安全使用,因为它将是 String 类型,而不是 String?

if let name = optionalName {
    greeting = "Hello, " + name
}

【讨论】:

    【解决方案3】:

    我来自红宝石世界,“Hello, (optionalName)”将返回“Hello,”,即如果 optionalName 为 nil,则插入空字符串。目前,如果 optionalName 为 nil,Swift 会打印“Hello, nil”,如果不是 nil,则会打印“Hello, Optional(“John”)”之类的内容。当使用 "Hello, (optionalName!)" 时,它会打印 "Hello, John",如果 optionalName 为 nil,则会导致运行时错误。对于 ruby​​ist 偶然发现这个想知道如何实现 ruby​​ 行为:

    let EMPTY_STRING = ""
    var greeting = "Hello, \(optionalName ? optionalName! : EMPTY_STRING)"
    

    【讨论】:

      猜你喜欢
      • 2015-08-20
      • 2016-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多