什么_:_:以及冒号和下划线的类似组合在Swift中是什么意思?

时间:2015-06-25 02:23:18

标签: ios swift oop

在阅读Swift的文档时,Apple通常使用functionName(_:name:)或类似的东西。这种模式究竟是什么有时是_:_:,有时只是_:_:name:。我认为它与参数简写有关,但我不确定,也无法在Swift的编程指南中找到解释。谢谢!

示例:

insert(_:atIndex:)

4 个答案:

答案 0 :(得分:10)

下划线表示该函数没有外部参数名称。 Apple's Swift Documentation就你何时编写自己的函数来谈论这个概念。

以编写此函数的情况为例(来自文档):

func sayHello(to person: String, and anotherPerson: String) -> String { ... }

如果您要使用该功能,请编写以下内容:

sayHello(to: "Bill", and: "Ted")

此签名为sayHello(to:and:)。 但是,如果我们想将该函数用作sayHello("Bill", "Ted"),该怎么办?我们如何表明我们不想要外部参数名称?那就是下划线的来源。我们可以将函数重写为:

func sayHello(person: String, _ anotherPerson: String) -> String { ... }

注意第一个参数不需要_,但后续的参数不会。第一个被推断为没有参数名称。这使得此调用的方法签名为sayHello(_:_:),因为您作为调用者没有命名参数。

更新Swift 3.0:

Swift 3.0平等对待所有参数。第一个参数现在需要一个下划线来表示外部参数名称的缺失。在上面的呼叫站点sayHello("Bill", "Ted")示例中,您的相应函数或方法声明必须是

func sayHello(_ person: String, _ anotherPerson: String) -> String { ... }

请注意在内部参数名称'person'之前添加下划线。

答案 1 :(得分:1)

下划线表示忽略的值。你可以在这里读更多关于它的内容: What's the _ underscore representative of in Swift References?

在文档中,它被用作通配符来表示带有未命名参数的函数。

答案 2 :(得分:0)

分享我的学习经历。

//MARK: Default
func join1(s1: String, s2: String, joiner: String) -> String {
    println("join1" + s1 + joiner + s2)
    return s1 + joiner + s2
}

//MARK: External Parameter Names
// To make the purpose of these String values clearer, define external parameter names for each join function parameter
func join2(string s1: String, toString s2: String, withJoiner joiner: String) -> String {
    println("join2" + s1 + joiner + s2)
    return s1 + joiner + s2
}

//MARK: External Names for Parameters with Default Values
func join3(string s1: String, toString s2: String, withJoiner joiner: String = " ") -> String {
    println("join3" + s1 + joiner + s2)
    return s1 + joiner + s2
}

//MARK: No External Names for Parameters with Default Values
func join4(s1: String, s2: String, joiner: String = " ") -> String {
    println("join4" + s1 + joiner + s2)
    return s1 + joiner + s2
}

//MARK: instead of an explicit external name
// You can opt out of this behavior by writing an underscore (_) instead of an explicit external name when you define the parameter. However, external names for parameters with default values are preferred.

func join5(s1: String, _ s2: String, _ joiner: String = " ") -> String {
    println("join5" + s1 + joiner + s2)
    return s1 + joiner + s2
}

//MARK: Shorthand External Parameter Names
// Provide an external parameter name with the same local parameter name
// Swift provides an automatic external name for any parameter that has a default value. The automatic external name is the same as the local name, as if you had written a hash symbol before the local name in your code.

func join6(#s1: String, s2: String, joiner: String = " ") -> String {
    println("join6" + s1 + joiner + s2)
    return s1 + joiner + s2
}

你可以看到如何使用它们

join1("s1", s2: "s2", joiner: "-")

join2(string: "s1", toString: "s2", withJoiner: "-")

join3(string: "s1", toString: "s2", withJoiner: "-")
join3(string: "s1", toString: "s2")

join4("s1", s2: "s2", joiner: "-")
join4("s1", s2: "s2")

join5("s1", "s2", "-")
join5("s1", "s2")

join6(s1: "s1", s2: "s2", joiner: "-")
join6(s1: "s1", s2: "s2")

答案 3 :(得分:-1)

来自Swift docs

  

函数参数可以同时具有本地名称(在...中使用)   函数的主体)和外部名称(用于调用时)   功能),如外部参数名称中所述。同样如此   对于方法参数,因为方法只是函数   与类型相关联。但是,本地名称的默认行为   功能和方法的外部名称不同。
  ...
  ......

     

具体来说,Swift [make]是方法中的第一个参数名称   默认情况下参数名称,[make]第二个和后续   默认情况下,参数名称为本地和外部参数名称。   此约定与您的典型命名和调用约定相匹配   熟悉编写Objective-C方法,并为之做好准备   表达方法调用,无需限定参数   名。

     

考虑Counter类的替代版本......

class Counter {
    var count: Int = 0
    func incrementBy(amount: Int, numberOfTimes: Int) {
        count += amount * numberOfTimes
    }
}
     

这个 incrementBy(_:numberOfTimes:)方法有两个参数 - 金额   和numberOfTimes。默认情况下,Swift将金额视为本地名称   仅限,但将numberOfTimes视为本地名称和外部名称。   您可以按如下方式调用该方法:

let counter = Counter()
counter.incrementBy(5, numberOfTimes: 3)
// counter value is now 15
     

您无需为第一个定义外部参数名称   参数值,因为它的目的是从函数名中清楚   incrementBy。然而,第二个论点是外部的   参数名称,以便在调用方法时明确其目的。

     

此默认行为有效地将方法视为您的方法   在numberOfTimes参数之前写了一个哈希符号(#):

func incrementBy(amount: Int, #numberOfTimes: Int) {
    count += amount * numberOfTimes
}
     

上述默认行为表示方法定义   Swift的编写方式与Objective-C相同,并且   以自然,富有表现力的方式被称为。

因此,要使方法的第二个参数的外部名称无效,您可以为外部名称显式写入“_”:

class Counter {
    var count: Int = 0
    func incrementBy(amount: Int, _ numberOfTimes: Int) {
        count += amount * numberOfTimes
    }
}

现在方法名的语法变为:

  

<强> incrementBy(__:__:)

语法告诉您如何调用该方法。在这种情况下,语法告诉您有两个未命名的方法参数,因此您可以像这样调用方法:

 incrementBy(3, 2)

如果方法名称是incrementBy(_:numberOfTimes:),语法会告诉您第一个参数是未命名的,而第二个参数的名称是numberOfTimes,因此您可以像这样调用方法:

 incrementBy(3, numberOfTimes:2)