什么是Swift References的_下划线代表?

Con*_*sed 138 declaration function objective-c swift

在Apple的文档的参考部分中有很多这种事情的实例:

func runAction(_action: SKAction!)

Objective-C'等效'是:

- (void)runAction:(SKAction *)action

让我感到非常重要的是(在Swift参考中)下划线后面有一个空格,而"动作"用斜体字写成.

但我无法弄清楚这是想传达什么.所以也许问题是......参考文献中使用的约定是否有参考?

- 这是我参考下划线使用的参考页面:https: //developer.apple.com/documentation/spritekit/sknode#//apple_ref/occ/instm/SKNode/runAction

更新

Swift 3对如何使用和命名函数/方法参数名称和参数标签进行了一些更改.这会对这个问题及其答案产生影响.@Rickster做了一个很棒的工作,回答了关于_underscores的一个不同的问题,在这些函数中清除了大部分内容,这里:为什么我需要在swift中使用下划线?

Aar*_* He 111

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

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

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

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

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

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

class Bar{
    func foo(s1: String, s2: String) -> String {
        return s1 + s2;
    }
}
Run Code Online (Sandbox Code Playgroud)

当你打电话时foo(),它被称为bar.foo("Hello", s2: "World").

但是,您可以通过_s2声明它的位置前使用来覆盖此行为.

func foo(s1: String, _ s2: String) -> String{
    return s1 + s2;
}
Run Code Online (Sandbox Code Playgroud)

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

回到你的情况,runAction是一种方法,因为它SKNode显然与类型相关联.因此,使用_before参数action可以在runAction没有外部名称的情况下调用.

Swift 2.0的更新

现在,函数和方法在本地和外部参数名称声明方面的工作方式相同.

现在,默认情况下使用外部参数名称调用函数,从第2个参数开始.此规则仅适用于纯Swift代码.

因此,通过_函数前面提供一个函数,调用者不必指定外部参数名称,就像您对方法所做的那样.

  • 困惑,如果`_`在第二个参数之前写,你的答案显然是足够的; 如果在`func runAction(_action:SKAction!)`中,`_`在第一个参数之前,或者你编写下面的代码`func foo(_ s1:String){//你的代码}`Xcode会给你一个警告,但是参考中有很多像`func bringSubviewToFront(_ view:UIView)`的代码,为什么? (9认同)
  • 所以基本上,它没有任何理由这样做,只是让每个人都感到困惑.真棒. (9认同)
  • 重要的是要注意Swift 3.0改变了一些东西.除非另有说明,否则所有标签都是必需的.所以第一个参数之前的`-`不再是无关紧要的.例如:`override func viewWillAppear(_ animated:Bool)`表示调用者(Objective-C代码)不会使用参数标签 (4认同)
  • 下划线称为"通配符模式"https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Patterns.html#//apple_ref/doc/uid/TP40014097-CH36-ID420 (2认同)

Dav*_*rry 85

下划线是用于指示丢弃值的通用标记.

在这种特定情况下,它意味着将调用该函数runAction(argument)而不是runAction(action:argument)

在其他情况下,它具有其他类似含义,例如:

for _ in 0..<5 { ... }
Run Code Online (Sandbox Code Playgroud)

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

在这方面:

let (result, _) = someFunctionThatReturnsATuple()
Run Code Online (Sandbox Code Playgroud)

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

  • 真正的答案是@ dasblinkenlight的回答和我的回答.他更精确地解决了这个具体案例,而我解决了更广泛的问题,_是什么意思? (4认同)
  • 您也可以使用丢弃符号来表示非常大的数字,使它们更具可读性,如下所示`let pi = 3.141_592_653_59` (4认同)

das*_*ght 13

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

func someFunction(externalParameterName localParameterName: Int)
Run Code Online (Sandbox Code Playgroud)

如果您不自己提供外部名称,Swift会为您定义的任何默认参数提供自动外部名称.使用下划线表示外部参数名称将退出此行为:

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

您可以在此处的" 带有默认值的参数的外部名称 "一节中阅读有关此行为的更多信息.

  • @Confused我的理解是`SK`的设计师不希望你两次写'action`,因为"action"已经是函数名称的一部分.换句话说,他们不希望你写`sprite.runAction(action:moveGroundSpritesForever)`.外部参数名称的目的是使您的代码"像句子一样读"; 两次使用`action`会破坏它的目的. (4认同)

Jak*_*lář 12

从Swift 3开始,默认情况下都需要所有参数标签.

您可以强制IDE隐藏参数标签_.

func foo(a: String) {
}

func foo2(_ a: String) {
}
Run Code Online (Sandbox Code Playgroud)

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

注意:这只能当使用a的是(外)参数标签(内部)变量名在同一时间.它是等价的 - func foo(a a: String)不会接受_.

为什么Apple使用它?

您可以看到Apple正在API中使用它.Apple的库仍然用Objective-C编写(如果没有,它们共享相同的函数名称,这些函数名称是为Objective-C语法设计的)

applicationWillResignActive(_ application: UIApplication)这样的函数会有冗余参数名application,因为它的函数名中已有应用程序.

你的榜样

func runAction(_ action: SKAction!)没有它的_标记就会被称为runAction(action:).参数名称action将是多余的,因为函数名称中已有一个参数名称.这就是目的以及为什么会这样.


smi*_*Bot 10

我认为这迫使Swift中的一个约定使它更接近于Objective-c,它更好地匹配了cocoa约定.在objc中,您没有(外部)命名您的第一个参数.相反,按照惯例,您通常在方法名称的后半部分包含外部名称,如下所示:

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

[someInstance myFancyMethodWithFirstName:@"John" lastName:@"Doe"];
Run Code Online (Sandbox Code Playgroud)

要使Swift api调用与objc一致,您需要抑制第一个参数的外部参数名称.

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

someInstance.myFancyMethodWithFirstName("John", lastName:"Doe")
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这个解释.先了解了Obj-C,你已经把事情搞清楚了.它还强调了在Swift中正确命名Method的重要性,即Method名称的后半部分应描述第一个参数,通常是Obj-C中的情况.好东西. (2认同)

fuj*_*471 5

实际上,用于定义方法的实际代码与Apple文档中的方法声明之间存在差异.我们以UIControl- addTarget:action:forControlEvents:方法为例,真正的代码是: 在此输入图像描述

但在文档中,它看起来像这样(在目标之前注意_): 在此输入图像描述

在实际代码中,_用于使第二个或后续参数的外部名称在调用方法时不显示,而在docs中,_在参数的本地名称之前指示当您调用方法或函数时,不应提供外部名称.

默认情况下调用函数时没有外部名称,除非您提供自己的函数或添加#之前(没有空格)参数的本地名称,例如,这是我们使用dispatch_after的方式: 在此输入图像描述

在文档中,它看起来像这样(注意三_): 在此输入图像描述

函数声明的约定与我在方法中描述的相同.