不同的用例有一些细微差别,但通常下划线表示“忽略此”。
当声明一个新函数时,下划线告诉 Swift 该参数在调用时不应该有标签——这就是您所看到的情况。更完整的函数声明如下所示:
func myFunc(label name: Int) // call it like myFunc(label: 3)
“label”是参数标签,调用函数时必须存在。 (从 Swift 3 开始,默认情况下所有参数都需要标签。)“name”是您在函数内使用的参数的变量名称。较短的形式如下所示:
func myFunc(name: Int) // call it like myFunc(name: 3)
这是一个快捷方式,可让您对外部参数标签和内部参数名称使用相同的单词。它相当于func myFunc(name name: Int)
.
如果您希望函数可以在没有参数标签的情况下调用,请使用下划线_
使标签什么都没有/被忽略。 (在这种情况下,如果您希望能够使用该参数,则必须提供内部名称。)
func myFunc(_ name: Int) // call it like myFunc(3)
在赋值语句中,下划线表示“不分配给任何东西”。如果您想调用返回结果但不关心返回值的函数,可以使用它。
_ = someFunction()
或者,就像您链接到的文章中一样,忽略返回元组的一个元素:
let (x, _) = someFunctionThatReturnsXandY()
当您编写实现某些已定义函数类型的闭包时,可以使用下划线来忽略某些参数。
PHPhotoLibrary.performChanges( { /* some changes */ },
completionHandler: { success, _ in // don't care about error
if success { print("yay") }
})
同样,当声明采用协议或重写超类方法的函数时,可以使用_
对于参数names忽略参数。由于协议/超类也可能定义参数没有标签,因此您甚至可以连续使用两个下划线。
class MyView: NSView {
override func mouseDown(with _: NSEvent) {
// don't care about event, do same thing for every mouse down
}
override func draw(_ _: NSRect) {
// don't care about dirty rect, always redraw the whole view
}
}
与最后两种样式有些相关:当使用绑定局部变量/常量的流控制结构时,您可以使用_
忽略它。例如,如果您想迭代一个序列而不需要访问其成员:
for _ in 1...20 { // or 0..<20
// do something 20 times
}
如果您在 switch 语句中绑定元组大小写,则下划线可以用作通配符,如下例所示(在Swift 编程语言 https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/ControlFlow.html#//apple_ref/doc/uid/TP40014097-CH9-ID120):
switch somePoint { // somePoint is an (Int, Int) tuple
case (0, 0):
print("(0, 0) is at the origin")
case (_, 0):
print("(\(somePoint.0), 0) is on the x-axis")
case (0, _):
print("(0, \(somePoint.1)) is on the y-axis")
default:
print("(\(somePoint.0), \(somePoint.1)) isn't on an axis")
}
最后一件事不太相关,但我将包括在内,因为(如评论所述)它似乎引导人们来到这里:下划线in标识符——例如var _foo
, func do_the_thing()
, struct Stuff_
— 对于 Swift 来说没有什么特别的意义,但在程序员中有一些用途。
名称中的下划线是一种样式选择,但在 Swift 社区中并不受欢迎,该社区对于使用 UpperCamelCase 表示类型和 lowerCamelCase 表示所有其他符号有严格的约定。
使用下划线作为符号名称的前缀或后缀是一种样式约定,历史上用于区分私有/仅供内部使用的符号与导出的 API。然而,Swift 对此有访问修饰符,因此这种约定在 Swift 中通常被视为不惯用。
一些带有双下划线前缀的符号(func __foo()
)潜伏在 Apple SDK 的深处:这些是使用 (Obj)C 符号导入到 Swift 中的NS_REFINED_FOR_SWIFT
属性。当 Apple 想要制作 (Obj)C API 的“更 Swifty”版本时,他们会使用它——例如,将与类型无关的方法变成泛型方法 https://github.com/apple/swift/blob/master/stdlib/public/SDK/Photos/PHChange.swift。他们需要使用导入的 API 来使精炼的 Swift 版本正常工作,因此他们使用__
使其保持可用,同时对大多数工具和文档隐藏它。