如何在Swift中创建_inline_递归闭包?

副手

递归对于Swift中的全局函数来说是微不足道的。例如:

func f()
{
    f()
}

但是,闭包不能指向自身。例如:

var f: (Void -> Void) =
{
    f()
}

产生以下错误:

Variable used within its own initial value

有没有解决方法?如何创建内联的递归闭包

副手

有一种解决方法:

func unimplemented<T>() -> T
{
    fatalError()
}

func recursive<T, U>(f: (@escaping (((T) -> U), T) -> U)) -> ((T) -> U)
{
    var g: ((T) -> U) = { _ in unimplemented() }

    g = { f(g, $0) }

    return g
}

recursive是一个接受闭包的函数(((T) -> U), T) -> U,其中((T) -> U)是对闭包的剥离版本的引用,并返回一个可用函数g

g最初被分配了一个伪函数(在调用时崩溃)。这样做是为了启用对新值的递归g,其中随输入值一起g传递到重要的是要注意in是指自身,而不是之前分配给它的伪函数。因此,每当在中引用参数时,它都是对的引用,而后者又会引用自身。fTgg = { f(g, $0) }((T) -> U)fg

此功能允许进行内联递归,例如:

recursive { f, x in x != 10 ? f(x + 1) : "success" }(0)

此函数总共重复11次,而无需声明单个变量。

更新:现在可以在Swift 3预览版6中使用!


就我个人而言,我觉得这是一个相当优雅的解决方案,因为我认为它可以将我的代码简化到最低限度。AY组合器方法,例如以下一种

func recursive<T, U>(_ f: (@escaping (@escaping (T) -> U) -> ((T) -> U))) -> ((T) -> U)
{
    return { x in return f(recursive(f))(x) }
}

让我返回一个函数,在那个转义闭包内一个转义闭包!

recursive { f in { x in x != 10 ? f(x + 1) : "success" } }(0)

如果不是内部@escaping属性,则上面的代码将无效它还需要另一组花括号,这使它看起来比我编写内联代码时所能适应的更加冗长。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在Swift中创建通用闭包

来自分类Dev

如何在Swift中创建通用闭包

来自分类Dev

如何在Swift中从闭包中获取数据

来自分类Dev

如何在Swift中调用超级闭包

来自分类Dev

如何在Swift中定义闭包数组?

来自分类Dev

如何在Swift中设置对闭包/函数的弱引用?

来自分类Dev

如何在Swift中“生成”闭包类型别名?

来自分类Dev

如何在Swift中获取初始的闭包变量?

来自分类Dev

如何在方法中调用闭包

来自分类Dev

如何在scala中实现闭包?

来自分类Dev

如何在闭包中制作原型?

来自分类Dev

如何在Swift中使用两个闭包作为参数来创建函数?

来自分类Dev

如何在Swift> 2.2中表示闭包中的可变参数?

来自分类Dev

如何在Swift中从Void返回类型的闭包中隐藏隐式返回

来自分类Dev

如何在Swift中从Void返回类型的闭包中隐藏隐式返回

来自分类Dev

是否可以在Swift中创建通用闭包?

来自分类常见问题

如何在Swift 3中记录函数的闭包参数的参数?

来自分类Dev

如何在 Swift 中将计算的闭包属性转换为闭包?

来自分类Dev

如何在 swift 4 的闭包中分配类属性

来自分类Dev

创建Swift闭包以创建UIView

来自分类Dev

在Swift中传递闭包

来自分类Dev

在Swift中重用闭包

来自分类Dev

Swift 中的宏闭包

来自分类Dev

如何访问Swift中闭包内部的变量?

来自分类常见问题

如何在泛型结构中定义const闭包

来自分类Dev

如何在系统方法中添加闭包?

来自分类Dev

如何在jQuery .each函数中添加闭包?

来自分类Dev

如何在Python中实现Javascript闭包?

来自分类Dev

如何在可选闭包中添加@noescape批注