我的代码遇到了一个问题,我试图理解为什么对add的初始调用失败并出现"缺少参数"错误,而当它被传递到另一个函数时成功运行,在不带参数标签的情况下调用它.

我在Why does Swift require parameter names if it also requires argument order?岁时发现了关于这个话题的讨论,但我很难掌握所有细节,也无法确定它与我的查询的相关性.

func add(x: Int, y: Int) -> Int {
    x + y
}

func wrapper(function: (Int, Int) -> Int) -> Int {
    function(1, 2)  // Why does this not produce a "Missing argument" error?
}

// "Missing argument" error
// print(add(1, 2))

// No Error - I think I understand why this works
print(add(x: 1, y: 2))  // Outputs: 3

// How does this work?
print(wrapper(function: add))  // Outputs: 3

推荐答案

这是怎么回事?

print(wrapper(function: add))  // Outputs: 3

事实1

wrapper是一个函数,它接收此类型的1个参数:

(Int, Int) -> Int

事实2

您的add函数的类型为

(Int, Int) -> Int

您可以使用Xcode确认这一点:

  1. 将您的函数赋给一个常量
  2. Ctrl +单击常量名称

enter image description here

结论

由于wrapper的参数类型与add相同,因此编译此代码

wrapper(function: add)

来自 comments 的其他问题

你能解释一下为什么在函数外部调用时需要参数,而在函数内部调用时不再需要参数吗?

因为:

  1. Swift中的闭包没有外部参数名.
  2. 只要输入类型和输出类型匹配,就可以在需要闭包的地方传递函数.

所以当你写下

wrapper(function: add)

您正在将add函数传递给wrapper. 这是允许的,因为类型确实匹配.

然后当你写下

func wrapper(function: (Int, Int) -> Int) -> Int {
    function(1, 2)  // Why does this not produce a "Missing argument" error?
}

在第二行中,您现在调用的是一个没有外部参数名称的closure.

Swift相关问答推荐

向文本元素添加背景色失败

避免嵌套导航TabView

如何在SWIFT中轻松格式化公制和英制使用的UnitVolume

如何将图像插入到矩形中

从Firebase播放音频文件不起作用

SwiftUI路径平滑连接两条线

macOS SwiftUI: 如何触发删除一个项目?

避免 `(())` 显式指定 Void 类型的枚举关联值

在PrimitiveSequence上引用实例方法xxx需要类型A和any B等效

如何在 macOS/AppKit 的窗口选项卡上接受拖动项目的放置?

如何判断一个值是否为 Int 类型

格式化大货币数字

如何从数据中读取以空结尾的字符串?

如何获得不同的插入和移除过渡动画?

如何删除标签和步进按钮之间的间距是 SwiftUI Stepper?

更新我的 pod 导致 GoogleDataTransport Umbrella 标头出现错误

Swift 5.0 编译器无法导入使用 Swift 4.2.1 编译的模块

如何在 SwiftUI 中创建带有图像的按钮?

如何使用 swift 在 tableview 中填充两个不同数组的两个部分?

在 xcode8 中找不到 ModuleName-Swift.h 文件