You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift函数内Closure两种写法的原理疑问与解析请求

闭包两种写法的区别与原理解析

先看你提到的两种代码实现:

第一种写法(书中示例)

func counter() -> () -> Int {
    var count = 0
    let incrementer: () -> Int = {
        count += 1
        return count
    }
    return incrementer
}

第二种写法(你的常用写法)

func counter() -> Int {
    var count = 0
    let incrementer = { () -> Int in
        count += 1
        return count
    }
    return incrementer()
}

核心区别与第一种写法的工作原理

这两种写法本质完全不同,前者绝不是仅仅加了类型注解,它实现了闭包最核心的「状态持久化」特性:

  • 第一个counter函数的返回值类型是() -> Int,意思是它返回的是一个无参数、返回Int类型的闭包(函数),而非直接返回一个Int值。
  • 当你调用let myCounter = counter()时,counter函数执行内部逻辑:创建局部变量count并初始化为0,定义闭包incrementer(该闭包会捕获外部的count变量),最后把这个闭包本身返回给myCounter。
  • 此时counter函数执行完毕,但因为闭包incrementer捕获了count,count不会被系统销毁,而是和闭包绑定在一起保存在内存中。
  • 之后每次调用myCounter(),都会触发闭包的执行逻辑:让绑定的count自增1并返回,所以多次调用的结果会是1、2、3……,状态持续保留。

第二种写法的局限性

你的写法里,counter函数的返回值是Int类型,调用counter()时,函数内部会创建新的count变量,定义闭包后立刻执行闭包,直接返回第一次自增的结果1。
每次调用counter(),都会重新创建count=0,执行闭包后返回1,完全没有状态持久化的能力,和第一种写法的核心功能完全不同。

关于类型注解

第一种写法里的: () -> Int只是明确标注了incrementer的类型,就算去掉这个注解,Swift也能通过闭包内容自动推断出它的类型,写法可简化为:

func counter() -> () -> Int {
    var count = 0
    let incrementer = {
        count += 1
        return count
    }
    return incrementer
}

所以类型注解不是关键,核心是返回闭包本身,从而让捕获的变量持续存在,实现计数器的状态保留。

内容的提问来源于stack exchange,提问作者neuraldag

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 20:07:55