不同的用例有一些细微差别,但下划线通常意味着"忽略这一点".
当声明一个新函数时,一个下划线告诉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)
.
如果希望在没有参数标签的情况下调用函数,可以使用下划线_
使标签为nothing/ignored.(在这种情况下,如果想使用参数,必须提供一个内部名称.)
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来忽略参数.由于protocol/superclass还可能定义参数没有标签,因此您甚至可以在一行中使用两个下划线.
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语句中绑定元组大小写,下划线可以用作通配符,如本例所示(从The Swift Programming Language分之一缩短为The Swift Programming Language分之一):
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")
}
最后一件不太相关的事情,但我将包括在内,因为(正如 comments 所指出的)它似乎把人们带到了这里:下划线in标识符——例如var _foo
、func do_the_thing()
、struct Stuff_
——对Swift来说没有什么特别的意义,但在程序员中有一些用途.
名称中的下划线是一种样式 Select ,但在Swift社区中并不首选,该社区对类型使用大写字母,对所有其他符号使用小写字母有着强烈的约定.
用下划线作为符号名的前缀或后缀是一种样式约定,历史上用于区分私有/内部专用符号和导出的API.然而,Swift对此有访问修饰符,因此在Swift中,此约定通常被视为非惯用.
一些带有双下划线前缀(func __foo()
)的符号潜伏在苹果SDK的深处:这些是使用NS_REFINED_FOR_SWIFT
属性导入Swift的(Obj)C符号.当苹果公司想要制作一个(Obj)C API的"更快速"版本时,比如to make a type-agnostic method into a generic method,他们就会使用这个.他们需要使用导入的API使改进后的Swift版本工作,因此他们使用__
来保持其可用性,同时对大多数工具和文档隐藏它.