【问题标题】:Why choose auto closure over string literal?为什么选择自动关闭而不是字符串文字?
【发布时间】:2019-10-25 08:36:01
【问题描述】:

我有一个关于自动关闭的问题。例如,我们可以有一个像这样具有自动关闭功能的函数

func logHello(ifFalse condition: Bool,
         message: @autoclosure () -> String
    ) {
    guard condition else {
        return
    }
    print("Assertion failed: \(message())")
}

之所以更多地使用自动闭包,是因为我们希望将闭包的执行延迟到函数体,但这样做有什么意义呢?

我可以有这样的东西

func logHello1(ifFalse condition: Bool,
              message: String
    ) {
    guard condition else {
        return
    }
    print("Assertion failed: \(message)")
}

根本不使用闭包,而只是闭包可能产生的最终结果。这不是更好吗?

我已经看到在断言​​和 swift 本机功能的其他实现中使用 aotuclosures,但这让我感到困惑,为什么我们不能只传递 aliteral 来代替闭包?

在这种情况下使用自动关闭有什么好处?

【问题讨论】:

标签: swift


【解决方案1】:

您似乎已经回答了您自己的问题:“因为我们希望延迟执行函数体的闭包。”在这种情况下,关键点是您可能永远不会评估字符串。如果断言为真,则无需计算字符串。

考虑一个具体的例子:

logHello(ifFalse: true, message: expensiveString())

使用自动关闭,expensiveString() 将永远不会被调用。如果没有,它将始终被调用,即使结果从未使用过。

根据我的经验,对于现代移动或桌面应用程序而言,这通常比它的价值要大得多。但这就是它的目标。对于服务器进程,日志记录性能是一个需要仔细考虑的严重问题,但我很少遇到移动或桌面上的日志记录性能问题,而这些问题最好通过完全删除日志记录语句来解决。

你说得对,与字符串 literal 相比没有性能优势,但如果这就是你的意思,message 参数应该是 StaticString,而不是 String。

【讨论】:

  • 感谢您的回答。但是我能问一下为什么选择闭包而不是文字吗?例如,像断言函数。将它作为字符串文字不是比闭包更直观(因为闭包意味着评估某些东西,在这种情况下它不会)。我只是无法克服这方面的困惑。
  • 我想我不明白你在这里所说的“字面意思”是什么意思。这意味着 Swift 中的 StaticString,我同意这通常应该是这样,但我认为这不是你真正的问题。闭包并不意味着“评估某事”。它们的意思是“可以评估的功能”。在您的示例中,该函数可能永远不会被评估。
  • 但是如果你看一下我提供的例子,我使用了字符串文字,它会执行相同的功能吗?
  • 是的,但是您可以传递字符串文字以外的其他内容。如果你想要求它是一个字符串字面量,你可以使用StaticString,但通常人们的意思是"failure evaluating: " + object.description,它不是一个字面量,而且计算起来可能很昂贵。
  • 是的,不管怎样……为什么要使用自动关闭?因为性能是一样的?在静态字符串上?或者,没有特别的原因,只是一种偏好?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-05
  • 1970-01-01
  • 1970-01-01
  • 2021-05-29
  • 1970-01-01
  • 1970-01-01
  • 2013-01-01
相关资源
最近更新 更多