快速引用中的_下划线代表什么?

在苹果文档的参考部分有很多这类事情的例子:

func runAction(_action: SKAction!)

目标 C 的“等价物”是:

- (void)runAction:(SKAction *)action

我突然意识到(在 Swift 引用中)在下划线和“ action”之后有一个空格是很重要的。

但我不明白这是什么意思。所以也许问题是... 有没有参考文献中使用的惯例?

——这是我在下划线使用中引用的页面: Https://developer.apple.com/documentation/spritekit/sknode#//apple_ref/occ/instm/sknode/runaction

更新

Swift 3对函数/方法参数名称和参数标签的使用和命名方式做了一些更改。这对这个问题和它的答案有影响。@ Rickster 在回答函数中的 _ 下划线这个不同的问题上做得非常好,这里: 为什么我需要快速下划线?

50094 次浏览

下划线是用于指示丢弃值的常规标记。

在这个特定的示例中,这意味着函数将作为 runAction(argument)而不是 runAction(action:argument)调用

在其他语境中,它还有其他类似的含义,例如:

for _ in 0..<5 { ... }

这意味着我们只想执行块5次,而不关心块内的索引。

在这种情况下:

let (result, _) = someFunctionThatReturnsATuple()

这意味着我们不关心元组的第二个元素是什么,只关心第一个元素。

参数声明前的标识符定义 外部参数名。这是调用方在调用函数时必须提供的名称:

func someFunction(externalParameterName localParameterName: Int)

如果您自己不提供外部名称,则 Swift 为您定义的任何默认参数提供自动外部名称。使用下划线作为外部参数名称可以避免这种行为:

在定义参数时,可以通过编写下划线(_)而不是显式的外部名称来选择不执行此行为。

您可以在 具有默认值的参数的外部名称给你一节中了解更多关于这种行为的信息。

这两个答案都是正确的,但我想再澄清一点。

_用于 修改方法的外部参数名行为

在文档的 方法的本地和外部参数名部分,它说:

Swift 在默认情况下为 方法中的第一个参数名称提供本地参数名称,并在默认情况下为第二个参数名称和后续参数名称提供 本地和外部参数名称

另一方面,函数默认情况下没有外部参数名。

例如,我们在类 Bar中定义了这个 foo()方法:

class Bar{
func foo(s1: String, s2: String) -> String {
return s1 + s2;
}
}

当您调用 foo()时,它被称为类似于 bar.foo("Hello", s2: "World")

但是 ,您可以通过在声明它的 s2前面使用 _来覆盖这种行为。

func foo(s1: String, _ s2: String) -> String{
return s1 + s2;
}

然后,当您调用 foo时,可以像 bar.foo("Hello", "World")那样简单地调用它,而不需要第二个参数的名称。

回到您的例子,runAction是一个方法,因为它显然与 SKNode类型相关联。因此,将 _放在参数 action之前,就可以在不使用外部名称的情况下调用 runAction

Swift 2.0更新

函数和方法现在可以在本地和外部参数名声明方面使用 同样的方式

函数现在通过默认使用外部参数名来调用,从第2个参数开始。此规则仅适用于纯 Swift 代码。

因此,通过在 功能前面提供一个 _,调用方将不必指定外部参数名,就像对 方法所做的那样。

我认为这迫使斯威夫特制定了一个公约,使其更接近目标 c,更好地符合可可公约。在 objecc 中,不会(在外部)命名第一个参数。相反,按照惯例,通常在方法名的后半部分包含外部名称,如下所示:

- (void)myFancyMethodWithFirstName:(NSString *)aFirstName lastName:(NSString *)aLastName;


[someInstance myFancyMethodWithFirstName:@"John" lastName:@"Doe"];

要使 Swift api 调用与 objecc 一致,需要禁止显示第一个参数的外部参数名。

func myFancyMethodWithFirstName(_ firstName:String, lastName:String);


someInstance.myFancyMethodWithFirstName("John", lastName:"Doe")

实际上,用于定义方法的真实代码与 Apple 文档中的方法声明之间存在差异。我们来看看 UIControl - addTarget: action: forControlEvents: 方法,例如,实际代码是: enter image description here

但是在文档中,它看起来像这样(注意 _ before target) : enter image description here

在实际代码中,_ 用于创建第二个或后续参数的外部名称 在调用方法时不出现,而在 docs 中 < strong > ,_ 在参数的本地名称之前,表明当调用方法或函数时,不应该提供外部名称。

在默认情况下调用函数时没有外部名称,除非您在参数的本地名称之前(没有空格)提供您自己的名称或添加 # ,例如,我们就是这样使用 事后派遣的: enter image description here

在文档中,它是这样的(注意三 _) : enter image description here

函数声明的约定与我为方法所描述的相同。

只是更直观一点。

enter image description here

正如您可以看到的,_只是省略了一个本地参数名称或没有。

由于 Swift 3 所有的参数标签都是 违约所要求的。

可以使用 _强制 IDE 隐藏参数标签。

func foo(a: String) {
}
    

func foo2(_ a: String) {
}

叫做 foo(a: "abc")foo2("abc")

注意: 只有当 a同时是 (外部)参数标签(内部)变量名时才能使用。相当于 func foo(a a: String)不接受 _

苹果为什么要使用它?

你可以看到苹果正在 API 中使用它。苹果的库仍然是用 Objective-C (如果不是,它们共享相同的函数名,这是为 Objective-C 语法设计的)编写的

applicationWillResignActive(_ application: UIApplication)这样的函数的 多余的参数名称应该是 application,因为它的函数名中已经有了 申请

你的榜样

func runAction(_ action: SKAction!)将被称为 没有它的 _标记像 runAction(action:)。 参数名称 action应该是 多余的,因为函数名中已经有一个参数。这就是它存在的目的和原因。