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

Swift调用非可选参数函数省略实参未编译报错且返回异常类型问题

Swift函数调用的异常行为解析

问题背景

测试Swift代码时发现异常行为,定义函数如下:

func makeIncrementer(number: Int) -> ((Int) -> Int) {
  func incrementer(inputNumber: Int) -> Int {
    return inputNumber+1
  }
  return incrementer
}

注:number参数未被使用,这是无意的错误,却引发了此异常行为。

正常调用let functionVariable = makeIncrementer(number: 7)时,输出(Function)和8,符合预期;但当调用写成let functionVariable = makeIncrementer(number: )时,Xcode未报错,编译运行后输出两次(Function)。

问题解答

1. 非可选参数为何能省略实参编译通过?

这是Swift的**部分应用(partial application)**特性导致的。当你写makeIncrementer(number: )时,并不是省略了实参,而是将原函数转换为一个等待接收剩余参数的新函数:原函数签名是(Int) -> ((Int) -> Int),部分应用后得到的新函数签名是(Int) -> ((Int) -> Int)——也就是你需要再给这个新函数传入一个Int值,它才会返回原本的incrementer函数。

因为原函数内部没有使用number参数,Swift允许这种写法,即使参数是非可选类型。部分应用本质是把多参数函数拆解成嵌套的单参数函数,这里相当于把makeIncrementer变成了一个“先接收number,再返回增量函数”的函数。

2. 为何会出现两个函数类型的对象?

当你执行let functionVariable = makeIncrementer(number: )时,functionVariable本身就是一个函数(类型为(Int) -> ((Int) -> Int)),打印它会输出(Function);当你调用这个函数(比如let innerFunc = functionVariable(7)),它会返回原函数内部的incrementer函数(类型为(Int) -> Int),再打印innerFunc又会输出一次(Function)。这就是你看到两次输出的原因——这是两个不同的函数对象:外层的部分应用函数,以及它返回的内层增量函数。

如果原函数内部使用了number参数(比如return inputNumber + number),makeIncrementer(number: )的写法依然合法,但此时必须给返回的外层函数传入Int值,才能得到绑定了对应number的增量函数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 11:40:08