考虑以下功能:
func whatever(foo: @autoclosure () -> Int) {
let x = foo()
print(x)
}
当然,我们可以像这样调用它:
whatever(foo: 5)
// prints: 5
但是,提供显式闭包参数会导致编译器抱怨:
whatever(foo: { 5 })
// Error: Function produces expected type 'Int'; did you mean to call it with '()'?
这是您的意图吗?阅读@自动闭包
的留档时,我没有找到关于参数是否始终被包装的语句,即使在提供闭包时也是如此。我对@自动闭包
的理解是:
接受闭包参数。如果参数不是闭包,但与闭包返回的类型相同,则包装它。
然而,我看到的行为是:无论如何都要包装参数。
一个更详细的例子使这在我看来很奇怪:
struct Defaults {
static var dispatcher: Defaults = ...
subscript<T>(setting: Setting<T>) -> T { ... }
struct Setting<T> {
let key: String
let defaultValue: () -> T
init(key: String, defaultValue: @escaping @autoclosure () -> T) {
self.key = key
self.defaultValue = defaultValue
}
}
}
extension Defaults.Setting {
static var nickname: Defaults.Setting<String> {
return Defaults.Setting(key: "__nickname", defaultValue: "Angela Merkel")
}
}
// Usage:
Defaults.dispatcher[.nickname] = "Emmanuel Macron"
现在假设我想散列设置
值的键:
extension Defaults.Setting {
var withHashedKey: Defaults.Setting<T> {
return Defaults.Setting(key: key.md5(), defaultValue: defaultValue)
// Error: Cannot convert return expression of type 'Defaults.Setting<() -> T>' to return type 'Defaults.Setting<T>'
}
}
为了澄清:defaultValue
的类型是()-
extension Defaults.Setting {
init(key: String, defaultValue: @escaping () -> T) {
self.init(key: key, defaultValue: defaultValue)
}
}
真正令人望而生畏的是,我可以简单地使用< code>@autoclosure
参数转发到< code>init,它就工作了。< br>
是我遗漏了什么,还是Swift的设计无法为< code>@autoclosure参数提供闭包变量?
Swift 期望您将一个生成 Int
的表达式传递给 whatever(foo:),
Swift 会将该表达式包装在类型 () 的闭包中 -
func whatever(foo: @autoclosure () -> Int) {
let x = foo()
print(x)
}
当你这样称呼它:
func whatever(foo: {5})
您传递的表达式将导致
()-
func whatever(foo: {5}())
请注意,由于 Swift
将 {5}()
包装在闭包中,因此在调用 whatever(foo:)
之前不会对其进行评估,但实际上调用会延迟,直到您评估 let x = foo()。
你可以通过在操场上运行来验证这一点:
func whatever(foo: @autoclosure () -> Int) {
print("inside whatever")
let x = foo()
print(x)
let y = foo()
print(y)
}
whatever(foo: { print("hi"); return 3 }())
输出:
inside whatever
hi
3
hi
3
如果你想要
任何东西(foo:
也可以取一个()-
func whatever(foo: @autoclosure () -> Int) {
print("autoclosure whatever")
let x = foo()
print(x)
}
func whatever(foo: () -> Int) {
print("closure whatever")
whatever(foo: foo())
}
whatever(foo: { print("two"); return 6 })
whatever(foo: { print("two"); return 6 }())
输出:
closure whatever
autoclosure whatever
two
6
autoclosure whatever
two
6
闭包(Closures)是自包含的功能代码块,可以在代码中使用或者用来作为参数传值。 Swift 中的闭包与 C 和 Objective-C 中的代码块(blocks)以及其他一些编程语言中的 匿名函数比较相似。 全局函数和嵌套函数其实就是特殊的闭包。 闭包的形式有: 全局函数 嵌套函数 闭包表达式 有名字但不能捕获任何值。 有名字,也能捕获封闭函数内的值。 无名闭包,使用轻量级语法,可以根据上下
主要内容:以下是纠正/补充内容:Swift 4中的Closures(闭包)类似于组织为块的自包含函数,并且像C和Objective C语言一样调用。 在函数内定义的常量和变量引用被捕获并存储在闭包中。 函数可以看作是闭包的特殊情况,它采用以下三种形式 - 全局函数 嵌套函数 闭包表达式 有名称,不捕获任何值 有名称,从封闭函数中捕获值。 未命名的闭包从相邻块中捕获值 Swift 4语言中的Closures(闭包)表达式遵循清晰,
问题内容: 鉴于: 有什么方法可以使参数(和)的类型也保持不变? 更改类型会出现以下错误: @escaping属性仅适用于函数类型 删除该属性后,代码将编译并运行,但由于闭包使函数的作用范围变大,因此似乎并不正确。 问题答案: 有一个SR-2552报告无法识别功能类型别名。这就是错误的原因。您可以通过扩展函数签名中的函数类型来解决: 编辑1 : 我实际上是在xcode 8 beta版本下,但尚未解
闭包作为参数(Taking closures as arguments) 现在我们知道了闭包是 trait,我们已经知道了如何接受和返回闭包;就像任何其它的 trait! 这也意味着我们也可以选择静态或动态分发。首先,让我们写一个获取可调用结构的函数,调用它,然后返回结果: fn call_with_one<F>(some_closure: F) -> i32 where F : Fn(i
问题内容: 目前,我正在执行在循环内执行闭包的代码。我想知道所有闭包何时完成执行。目前,我正在使用一个计数器,并在关闭完成时将其递增,然后将其与要执行的时间进行比较。代码如下 有没有计数器的更好的方法。谢谢。 问题答案: 您可以为此使用。它的工作就像计数信号灯一样。您可以通过调用来增加计数,并通过来减少计数。您可以使用以下命令安排闭包在计数达到0时执行:
问题内容: 我正在尝试将项目更新为Swift 3.0,但遇到了一些困难。我收到下一个错误:“转义的闭包只能按值显式捕获inout参数”。 问题出在此函数内部: 有人可以帮我解决这个问题吗? 问题答案: 仅将参数用于异步任务是一种滥用–就像在调用函数时一样,传递给参数的调用者的值不会更改。 这是因为它不是传递引用,它只是参数的可变影子副本,该副本在函数退出时写回到调用方–并且由于异步函数立即退出,因