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
相关产品推荐
相关产品推荐

