为什么我需要快速下划线?

这里说:“注意: _表示”我不关心这个值“,但是来自JavaScript,我不明白这是什么意思。

我可以打印这些函数的唯一方法是在参数前使用下划线:

 func divmod(_ a: Int, _ b:Int) -> (Int, Int) { return (a / b, a % b) } print(divmod(7, 3)) print(divmod(5, 2)) print(divmod(12,4)) 

没有下划线,我必须这样写,以避免任何错误:

 func divmod(a: Int, b:Int) -> (Int, Int) { return (a / b, a % b) } print(divmod(a: 7, b: 3)) print(divmod(a: 5, b: 2)) print(divmod(a: 12,b: 4)) 

我不明白这个下划线的用法。 何时,如何以及为什么使用这些下划线?

对于不同的用例有一些细微差别,但通常下划线意味着“忽略这个”。


当声明一个新的函数时,下划线告诉Swift参数在调用的时候不应该有标签 – 这就是你所看到的情况。 更完整的函数声明如下所示:

 func myFunc(label name: Int) // call it like myFunc(label: 3) 

“label”是一个参数标签,当您调用函数时必须存在。 (从Swift 3开始,默认情况下所有参数都需要标签。)“name”是在函数中使用的参数的variables名称。 一个简短的forms如下所示:

 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() 

当你编写一个实现一些定义的函数types的闭包时,你可以使用下划线忽略某些参数。

 PHPhotoLibrary.performChanges( { /* some changes */ }, completionHandler: { success, _ in // don't care about error if success { print("yay") } }) 

类似地,当声明一个采用协议的函数或者覆盖超类方法时,可以使用_作为参数名称来忽略参数。 由于协议/超类也可能定义参数没有标签,所以甚至可以在一行中结束两个下划线。

 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 } } 

与最后两种风格有些相关:当使用绑定局部variables/常量的stream控制结构时,可以使用_来忽略它。 例如,如果你想迭代序列而不需要访问其成员:

 for _ in 1...20 { // or 0..<20 // do something 20 times } 

如果你在switch语句中绑定了元组case,那么下划线可以作为通配符来使用,就像这个例子(缩写为Swift编程语言中的一个 ):

 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") } 
 func divmod(_ a: Int, _ b:Int) -> (Int, Int) { return (a / b, a % b) } func divmod(a: Int, b:Int) -> (Int, Int) { return (a / b, a % b) } 

_是参数名称的占位符。 在你的例子中,你以不同的方式调用它们,在第二个函数中,你需要写出参数名称a: 1

Swift的函数名称约定是funcName(param1:param2:) ,它需要_作为占位符来创build函数的名称。

在名字中,名字是

 divmod(_:_:) 

而第二个是

 divmod(a:b:) 

自从Swift 3以来,在函数调用中指定参数名称已成为强制 – 即使是第一个。 所以,因为这可能会导致在swift 2中编写代码的巨大问题,您可以在声明中使用下划线来防止在调用时写入参数名称。 所以在这种情况下,它是说“不关心外部参数名称”。 其中外部参数名称是你所调用的函数外的参数(on call)不在里面。 这些外部参数名称被称为参数标签。 http://ericasadun.com/2016/02/09/the-trouble-with-argument-labels-some-thoughts/ …看看参数是如何给出两个名字? 以及第一个是下划线正在去的地方。希望这有助于,并且询问是否仍然困惑。