如何将@noescape 注释添加到可选闭包
Posted
技术标签:
【中文标题】如何将@noescape 注释添加到可选闭包【英文标题】:How to add @noescape annotation to optional closure 【发布时间】:2015-11-18 12:13:42 【问题描述】:我的函数有这个签名:
func foo(bar: String, baz: ((String) -> ())? = nil)
现在我想让self
在给定的闭包内转义。
但是当我尝试这个时:
func foo(bar: String, @noescape baz: ((String) -> ())? = nil)
编译器抱怨:
@noescape may only be applied to parameters of function type
是否可以在可选参数中使用它?
【问题讨论】:
它不能与可选功能一起使用。如果您删除? = nil
它可以工作。
感谢您的快速回复,我知道删除? = nil
有效,让我们看看是否有人有不同的想法
我的编译器也抱怨。我可以知道,你为什么需要这个?我认为 noescape 告诉“执行完成后保证不需要它”。可选意味着该值存在于两种不同的状态。如果将 nil 设置为可选值,则仍然存在一些对其的引用。如果闭包是可选的,则闭包可以为零,但仍然存在对它的引用。 noescape 似乎更像是“临时的”......非常有趣的问题!
我希望能够向foo
发送或不发送闭包,但如果我这样做了,我不想在我的闭包中使用self.
。是的,闭包不会被异步存储或调用
我也有这个问题,不明白为什么不能将@noescape 添加到可选闭包中(除非语言设计者还没有解决这个问题)。
【参考方案1】:
要求
如果您的要求如下:
baz
参数是closure
baz
参数标有@noescape
(因为你想在闭包代码中省略self
)
baz
参数在调用foo
期间可以省略
解决方案
那么你可以使用下面的语法
func foo(bar: String, @noescape baz: ((String) -> ()) = _ in )
如您所见,与您的代码的主要区别在于:
这里的baz
不是optional type
(但它是一个“可选参数”)
其默认值为empty closure
而不是nil
值。
示例
根据您的要求,您现在可以将闭包传递给baz
,而无需使用self
class Boo
let world = "world"
func boo()
foo("hello") (something) -> () in
print(world)
你也可以省略baz
参数
class Boo
let world = "world"
func boo()
foo("hello")
更新:使用返回类型不同于 Void 的闭包
在下面的评论中,用户 TadeasKriz
询问了如何将这种方法与返回值与 Void
不同的闭包一起使用。
这就是解决方案
func foo(bar: String, @noescape baz: ((String) -> (Int)) = _ in return 0 )
这里的baz
参数确实需要一个带有String
类型的1 个参数和Int
类型的返回值的闭包。
如您所见,我为参数添加了一个默认值,一个确实返回0
的闭包。请注意,将永远不会使用默认闭包,因此您可以将 0
替换为您想要的任何 Int
值。
现在您可以决定是否使用将您的闭包传递给baz
参数
class Boo
let world = "world"
func boo()
foo("hello") (something) -> Int in
print(world)
return 100
或者,同样,您可以完全省略 baz
参数。
class Boo
let world = "world"
func boo()
foo("hello")
【讨论】:
很棒的解决方法,而 Swift 不允许“正确的方式” 不幸的是,当闭包的返回类型不是 Void 时,它没有帮助。 例如:func foo(bar: String, @noescape baz: (String -> MyAwesomeType) = _ in )
.
我最终解决了这个问题:func foo(bar: String, @noescape baz: (String -> MyAwesomeType?) = _ in nil )
@TadeasKriz:我为我的答案添加了更新。现在您可以使用返回类型不同于Void
的闭包。以上是关于如何将@noescape 注释添加到可选闭包的主要内容,如果未能解决你的问题,请参考以下文章