swift中的评价策略

swift中的评价策略,swift,Swift,**第一种方法 func show(value: Int?, or error: String) { if let isValue = value { print("Found: \(isValue)") } else { print(error) } } show(value: 5, or: "No value found") //print "Found: 5" 我想从上面的代码中知道,即使我发现值非nil,并且在函数体中有条件代码

**第一种方法

func show(value: Int?, or error: String) {
    if let isValue = value {
        print("Found: \(isValue)")
    } else {
        print(error)
    }
}

show(value: 5, or: "No value found")
//print "Found: 5"
我想从上面的代码中知道,即使我发现值非nil,并且在函数体中有条件代码,传递的错误字符串
未找到值
仍将在幕后计算?每次我们尝试打开可选的

**第二种方法

func show(value: Int?, or error: @autoclosure () -> String) {
    if let isValue = value {
        print("Found: \(isValue)")
    } else {
        print(error())
    }
}
show(value: 5, or: "No value found")
//print "Found: 5"

或者这种方法可以工作,它只在需要时计算错误表达式。或者两者在记忆中都是相同的。我想知道这两种方法的答案。

您的解释是正确的:第一个代码急切地准备
错误
字符串,而第二个代码延迟字符串构造,直到需要为止

在您的情况下,
@autoclosure
并没有给您带来多少优势,因为从字符串文本构造
字符串
与构造闭包一样便宜

以下是区分变得重要的场景:

show(value: optValue, or: "No value of \(description) found for user \(user)")

既然必须通过插入字符串来构造
错误
字符串,那么该操作就不再便宜了,因此使用
@autoclosure
延迟它就非常有意义了。假设错误情况相对较少发生,构造一次性闭包的成本将低于插入字符串的成本。

不要过早地进行优化。它不需要评估任何东西。这是一个字符串常量。使用闭包而不是直接字符串值有什么好处吗?不,您在这里使用的是字符串常量,对吗?那么否。是的,默认情况下参数是常量。您是否可以检查此链接并转到
将错误作为表达式传递
。我对自动关闭有点困惑。john sundell提到过自动关闭
我们只在需要时计算错误表达式,而不是每次尝试打开可选文件时都要计算错误表达式。
但是在代码保护语句中,处理延迟功能并不是正确的关闭。这就是为什么我在这个问题中问你关于字符串vs@autoclosure的求值问题。@Tanzz是的,在第一个示例中,
error
参数是“急切地”构造的,因此内存被分配给错误字符串。在第二个例子中,闭包是构造的,因此内存分配给闭包,而不是字符串(除非字符串实际被使用)。@Tanzz我不知道有什么好的教程。就分配字符串与分配闭包而言,闭包通常需要比字符串更少的内存。对于固定长度的字符串,差异很小,因为分配的内存量对代码计时的影响非常小。当你插入字符串时,实际的节省会出现,因为构造插入字符串的成本更高。好吧,swift文档中提到的@autoclosure是
autoclosure可以让你延迟计算,因为在你调用闭包之前,里面的代码不会运行。延迟求值对于有副作用或计算开销大的代码很有用,因为它可以让您控制代码求值的时间。
现在我得到了正确的结果。如果我使用插值字符串来处理该错误,每当该函数调用并尝试解包可选时,该字符串也会被分配。这是一个很大的工作,但对于闭包,至少字符串只在需要时进行计算,如果每次值都是非零而不是插值字符串,则只需在内存中分配闭包即可。@Tanzz正式名称为延迟计算。请注意,闭包本身是急切创建的;延迟的是闭包结果的计算。