在这里它说:"注意:_意思是"我不关心那个价值",但是来自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))
Run Code Online (Sandbox Code Playgroud)
如果没有下划线,我必须这样写它以避免任何错误:
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))
Run Code Online (Sandbox Code Playgroud)
我不明白这个下划线用法.何时,如何以及为何使用这些下划线?
ric*_*ter 299
不同的用例有一些细微差别,但通常下划线意味着"忽略这个".
在声明一个新函数时,下划线告诉Swift该参数在被调用时应该没有标签 - 这就是你所看到的情况.更全面的函数声明如下所示:
func myFunc(label name: Int) // call it like myFunc(label: 3)
Run Code Online (Sandbox Code Playgroud)
"label"是参数标签,在调用函数时必须存在.(并且从Swift 3开始,默认情况下所有参数都需要标签.)"name"是您在函数内使用的参数的变量名.较短的表单如下所示:
func myFunc(name: Int) // call it like myFunc(name: 3)
Run Code Online (Sandbox Code Playgroud)
这是一个快捷方式,允许您对外部参数标签和内部参数名称使用相同的单词.它相当于func myFunc(name name: Int).
如果希望函数在没有参数标签的情况下可调用,则使用下划线_使标签无任何/忽略.(在这种情况下,如果您希望能够使用该参数,则必须提供内部名称.)
func myFunc(_ name: Int) // call it like myFunc(3)
Run Code Online (Sandbox Code Playgroud)
在赋值语句中,下划线表示"不分配给任何东西".如果要调用返回结果但不关心返回值的函数,可以使用此方法.
_ = someFunction()
Run Code Online (Sandbox Code Playgroud)
或者,与您链接的文章一样,忽略返回元组的一个元素:
let (x, _) = someFunctionThatReturnsXandY()
Run Code Online (Sandbox Code Playgroud)
当您编写实现某些已定义函数类型的闭包时,可以使用下划线忽略某些参数.
PHPhotoLibrary.performChanges( { /* some changes */ },
completionHandler: { success, _ in // don't care about error
if success { print("yay") }
})
Run Code Online (Sandbox Code Playgroud)
同样,在声明采用协议的函数或覆盖超类方法时,可以使用_参数名来忽略参数.由于协议/超类也可能定义参数没有标签,因此您甚至可以连续使用两个下划线.
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
}
}
Run Code Online (Sandbox Code Playgroud)
与最后两种样式有些相关:当使用绑定局部变量/常量的流控制构造时,您可以使用_忽略它.例如,如果要迭代序列而不需要访问其成员:
for _ in 1...20 { // or 0..<20
// do something 20 times
}
Run Code Online (Sandbox Code Playgroud)
如果你在一个switch语句结合元组的情况下,下划线可以作为通配符,在这个例子中(从一个缩短的雨燕编程语言):
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")
}
Run Code Online (Sandbox Code Playgroud)
这似乎不太相关的最后一两件事,但我会因为包括(通过评论指出的),似乎在这里带领人们:下划线在标识符-例如var _foo,func do_the_thing(),struct Stuff_-表示没有什么特别的斯威夫特,但有几个用途在程序员中间.
名称中的下划线是样式选择,但在Swift社区中不是首选,后者具有关于对类型使用UpperCamelCase和对所有其他符号使用lowerCamelCase的强烈约定.
使用下划线对符号名称进行前缀或后缀是一种样式约定,历史上用于区分私有/仅内部使用符号和导出的API.但是,Swift具有访问修饰符,因此这种约定在Swift中通常被视为非惯用语.
与双下划线前缀几个符号(func __foo())潜伏在苹果公司的软件开发工具包的深处:这些(的OBJ)C符号使用导入斯威夫特NS_REFINED_FOR_SWIFT属性.当Apple想要制作一个"更加Swifty"版本的(Obj)C API时,Apple会使用它 - 例如,将类型无关的方法变成泛型方法.他们需要使用导入的API来使精炼的Swift版本工作,因此他们使用它__来保持它可用,同时将其隐藏在大多数工具和文档中.
Moj*_*ini 24
除了接受的答案之外,其中一个用例_是您需要在代码中编写一个长数字
这不是一个简单的人类可读的:
let x = 1000000000000
Run Code Online (Sandbox Code Playgroud)
? 您可以添加_数字以使其更具人类可读性:
let x = 1_000_000_000_000
Run Code Online (Sandbox Code Playgroud)
您可能会在 Swift 中遇到接口以_. 虽然他们在技术上宣布public,但以下划线开头是不是认为这个包的公共接口的一部分。我们可能会在任何版本中删除或更改它们,恕不另行通知,包括次要版本。
例如,官方 Swift Collections 存储库中的@_exportedImport更多示例
?? 干脆不要使用它们,或者您应该手动跟踪更改。
从Swift 3开始,在函数调用上指定参数名称已成为必需-甚至对于第一个。因此,由于这可能会对swift 2中编写的代码造成巨大问题,因此可以在声明中使用下划线,以防止在调用时必须写入参数名称。因此,在这种情况下,就是说“不在乎外部参数名称”。外部参数名称是您在函数外部(调用时)而不是内部调用的参数。这些外部参数名称称为参数标签。http://ericasadun.com/2016/02/09/the-trouble-with-argument-labels-some-thoughts/ ...看到参数是如何给两个名字的?好首先是下划线的去向。希望这会有所帮助,并询问是否仍然感到困惑。
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)
}
Run Code Online (Sandbox Code Playgroud)
是_参数名称的占位符。在您的示例中,您以不同的方式调用它们,在第二个函数中,您需要编写参数 name a: 1。
Swift 的函数名称约定是funcName(param1:param2:),它需要_作为占位符来创建函数的名称。
在第一个名字中,名字是
divmod(_:_:)
Run Code Online (Sandbox Code Playgroud)
而第二个是
divmod(a:b:)
Run Code Online (Sandbox Code Playgroud)