一尘不染

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

swift

在这里,它说,“注:_意思是‘我不关心这个值’”,但是从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))

我不理解此下划线用法。我何时,如何以及为什么使用这些下划线?


阅读 223

收藏
2020-07-07

共1个答案

一尘不染

不同的用例有一些细微差别,但是通常下划线表示“忽略此”。


在声明一个新函数时,下划线告诉Swift调用时该参数不应带有标签-就是这种情况。完整的函数声明如下所示:

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

“标签”是参数标签,在调用函数时必须存在。(并且从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") }
    })

同样,在声明采用协议或覆盖超类方法的函数时,可以使用_参数 忽略参数。由于协议/超类也可能定义该参数没有标签,因此您甚至可以连续两个下划线结尾。

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



缩写相比):

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

这似乎不太相关的最后一两件事,但我会因为包括(通过评论指出的),似乎在这里带领人们:下划线 标识符-例如var _foofunc do_the_thing()struct Stuff_-手段没有什么特别的斯威夫特,但有几个用途在程序员之间。

名称中的下划线是样式的选择,但是在Swift社区中并不是首选,Swift社区对于将UpperCamelCase用于类型并将lowerCamelCase用于所有其他符号具有严格的约定。

使用下划线在符号名称前添加前缀或后缀是一种样式约定,在历史上一直用于区分导出的API中的专用/仅供内部使用的符号。但是,Swift为此具有访问修饰符,因此该约定在Swift中通常被视为非惯用语。

func __foo()在Apple
SDK的深度中,一些带有双下划线前缀()的符号潜伏着:这些是使用NS_REFINED_FOR_SWIFT属性导入到Swift的(Obj)C符号。Apple想要制作(Obj)C
API的“更快速”版本时使用Apple,例如,将与类型无关的方法转换为通用方法。他们需要使用导入的API来使精致的Swift版本起作用,因此他们使用__使其保持可用状态,同时将其隐藏在大多数工具和文档中。

2020-07-07