swift - 为什么我需要 swift 中的下划线?

标签 swift

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 开始,默认情况下所有参数都需要标签。)“名称”是您在函数内部使用的该参数的变量名称。较短的形式如下所示:

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

同样,当声明一个采用协议(protocol)或重写父类(super class)方法的函数时,您可以对参数名称使用_来忽略参数。由于协议(protocol)/父类(super class)也可能定义参数没有标签,您甚至可以在一行中使用两个下划线。

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

与后两种风格有点相关:当使用绑定(bind)局部变量/常量的流程控制结构时,您可以使用 _ 忽略它。例如,如果您想迭代一个序列而不需要访问其成员:

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

如果您在 switch 语句中绑定(bind)元组大小写,则下划线可以用作通配符,如下例所示(从 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 社区中不是首选,因为 Swift 社区有关于类型使用 UpperCamelCase 而所有其他符号使用 lowerCamelCase 的严格约定。

使用下划线为符号名称添加前缀或后缀是一种样式约定,历史上用于区分私有(private)/仅供内部使用的符号与导出的 API。然而,Swift 对此有访问修饰符,因此这种约定在 Swift 中通常被视为非惯用的。

一些带有双下划线前缀的符号 (func __foo()) 潜伏在 Apple SDK 的深处:这些是使用 NS_REFINED_FOR_SWIFT属性。 Apple 在他们想要制作 (Obj)C API 的“更 Swifty”版本时使用它——例如,to make a type-agnostic method into a generic method .他们需要使用导入的 API 来使改进的 Swift 版本工作,因此他们使用 __ 来保持它可用,同时将它隐藏在大多数工具和文档中。

关于swift - 为什么我需要 swift 中的下划线?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39627106/

相关文章:

ios - 方法参数需要类型和协议(protocol)

ios - 如何删除在 MDCTextField 外部点击时关闭键盘操作

ios - 将更多项目添加到 ScrollView 顶部时,将现有项目向下移动

swift - 将 Cookie 设置为来自 Swift NSURLSession 的 HTTP POST 请求

ios - 由于错误而跳过安装 .framework 二进制文件

swift - 在 Swift 中异步挂载卷

ios - NavigationBar 为一个 View 设置 TitleColor

ios - Swift 在没有开关的情况下获取枚举中的关联值

ios - 如何引用 cellForRowAtIndexPath 之外的单元格

ios - 如何在 ios (swift) 的表格单元格中从 firebase 读取图像?