What to do _: _: and similar combinations of colon and underline mean in Swift?

When reading Swift documentation, Apple usually uses functionName(_:name:) or something similar. What exactly is this pattern, which is sometimes equal to _:_: sometimes just _: and _:name: I think this is due to the reduction of the parameter, but I am not sure and cannot find an explanation in the Swift programming guide. Thanks!

Example:

 insert(_:atIndex:) 
+6
source share
4 answers

An underscore indicates that the function does not have an external parameter name. The Apple Swift Documentation talks about this concept in terms of when you write your own functions.

Take the case when you write this function (from the documentation):

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

If you used this function, you should write the following:

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

The signature for this will be sayHello(to:and:) . However, what if we want to use a function like sayHello("Bill", "Ted") ? How would we indicate that we do not need to have an external parameter name? Well, that is where it is emphasized. We could rewrite this function as:

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

Note that the first parameter does not need _, but the subsequent ones will. The first conclusion is that it does not have a parameter name. This makes the method signature for this call to sayHello(_:_:) , because you, as the caller, do not have a named parameter.

Update Swift 3.0:

Swift 3.0 handles all parameters the same way. The first parameter now requires an underscore to indicate the absence of an external parameter name. In the above example of having sayHello("Bill", "Ted") on the call site, your corresponding function or method declaration should be

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

Note the addition of an underscore in front of the name of the internal person parameter.

+8
source

The underlined designation is ignored. You can read more about it here: What is the underscore representative in Swift References?

In the documentation, it is used as a wildcard to indicate a function that accepts an unnamed parameter.

+1
source

share your learning experiences.

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

And you can see how to use them

 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") 
0
source

From Swift docs :

Function parameters can have both a local name (for use within a function) and an external name (for use when calling a function), as described in "External parameter names". The same is true for method parameters, because methods are simply functions that are associated with a type. However , the default behavior of local names and external names are different for functions and methods.
...
...

In particular, Swift [makes] the name of the first parameter in the local method default parameter name and [makes] the second and subsequent parameter names, both local and external default parameter names. This convention corresponds to the typical naming and calling convention, which you will be familiar with writing Objective-C methods and express calls without having to define your parameter names.

Consider this alternative version of the Counter class ...

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

This incrementBy (_: numberOfTimes :) method has two parameters - quantity and numberOfTimes. By default, Swift treats the sum as a local name only, but processes numberOfTimes both the local and the external name. You call the method as follows:

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

You do not need to determine the name of the external parameter for the first value of the argument, since its purpose is clear from the name of the incrementBy function. The second argument, however, qualifies the parameter name externally to clear its purpose when the method is called.

This default behavior effectively handles the method as if you had a hash (#) before the numberOfTimes parameter:

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

The default behavior described above means that the method definitions in Swift are written in the same grammatical style as Objective-C and are invoked in a natural, expressive way.

So, to invalidate the external name of the second parameter of the method, you can explicitly write '_' for the external name:

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

The syntax for the method name will now look like this:

incrementBy (__: __ :)

The syntax tells you how to call the method. In this case, the syntax tells you that there are two unnamed arguments to the method, so you call the method as follows:

  incrementBy(3, 2) 

If the method name is incrementBy(_:numberOfTimes:) , the syntax tells you that the first argument is unnamed and the second argument is numberOfTimes, so you call the method as follows:

  incrementBy(3, numberOfTimes:2) 
-1
source

Source: https://habr.com/ru/post/989705/


All Articles