Here它说,"注意:_的意思是"我不在乎那个值",但来自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"是在函数中使用的参数的变量名.较短的形式如下所示:

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 _foofunc 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版本工作,因此他们使用__来保持其可用性,同时对大多数工具和文档隐藏它.

Swift相关问答推荐

如何模拟可以立即返回和/或与Deliverc/await同步返回的CompletionButtons风格代码?

为表单部分赋予背景 colored颜色 /渐变

JSON如何解码空对象

如何在SWIFT中解码Instagram Backup中的字符串?

如何将CodingKeys作为数组而不是枚举传递到类外部的函数中?

如何把多个可观测性变成一个完备性?

无法创建MKAssociateRegion对象

同时具有每个文本的标识符的文本组的可扩展性标识符

如何使用AsyncTimerSequence获取初始时钟,然后在指定的时间间隔内开始迭代?

更改 SwiftUI 中按钮矩阵的填充 colored颜色

当模式以编程方式关闭时在父视图控制器中触发操作

使用UICollectionViewFlowLayout创建水平的UICollectionView,并同时将单元格对齐到左边和右边的能力

暂停我的 AR 会话并清除变量和锚点的功能

Swift 数组拆分成重叠的块

如何从 Swift 中隐藏 Objective-C 类接口的一部分?

ConfirmationDialog取消swiftui中的错误

为 ObservedObject 和 State 对象配置预览

try 制作一个 Swift 扩展来替换字符串中的多次出现

macOS 守护进程应该由Command Line ToolXcode 模板制作吗?

无法分配给属性:self 是不可变的,我知道如何修复但需要理解