Difference between two simple functions in Swift - swift

I am currently studying Swift and I am wondering what is the difference between these two functions, and which is the most correct one?
func sayName (name: String) {
println("Name is, \(name)")
}
func sayNewName (name: String) -> String {
return "Name is, + name"
}

The first prints a line to standard output. It takes a parameter, name, of type String.
The second one explicitly declares both a return type (of type String) and also returns a value that can be used by any subsequent functions, etc.
There is no "most correct one" in this case, they just serve different purposes.
In other words, in the first function, you can't "do" anything with its return value. It is simply a function whose purpose is in its side effects, whereas the second function returns a value that can be used.

Related

How to access an anonymous parameter within a method?

How can I access the str label inside the function body? If it's impossible then why the compiler doesn't throw an error ?
class Test {
func methodA(str _: String) {
}
func methodB() {
methodA(str: "")
}
}
Using _ for the parameter name means you have no need to use the parameter within the method. The str argument label has no use inside the implementation of the method itself. It's only useful in the calling syntax.
If you actually have a need to use a parameter in a method, don't give it the anonymous name of _. Give it a useful name so it can be referenced in the implementation of the method. Or simply remove the _ so both the parameter name and label are the same.
Either do:
func methodA(str: String) {
// do something with str
}
or something like:
func methodA(str val: String) {
// do something with val
}
In both cases the caller is the same as you currently have:
methodA(str: "")
The only time you would want an anonymous parameter name is if your implementation of the method doesn't actually make use of the parameter. Maybe the implementation isn't finished or over time it's changed and a parameter isn't needed any more and you don't want to update lots of existing code calling the method.
There is a compiler setting to get warnings about unused parameters. If you have an unused parameter, changing the name to _ eliminates the warning.
See Function Argument Labels and Parameter Names in the Swift book (though it doesn't cover this case of anonymous parameter names).

Swift: function compiles, no warning, but can this function even be used?

In Swift it seems to be possible to create a variadic function with a vararg parameter which isn't the last parameter of the function.
I created the following function:
func test1(_ array: String..., _ tag: String){
print("[\(tag)] array: \(array)")
}
Because it's possible to define a vararg parameter without making it the last parameter I suspected that the Swift compiler would just take the last argument and make it the argument for the second parameter.
test1("Hello", "World", "Greeting")
But this doesn't work, which is not too strange.
This doesn't work either:
let arrayOfStrings: [String] = ["Hello", "World"]
test1(arrayOfStrings, "Greeting")
Obviously giving the second parameter a label works.
func test2(_ array: String..., tag: String){
print("[\(tag)] array: \(array)")
}
But I decided to make another try. This function compiles doesn't generate a warning, but can I even use it?
func test3(_ array: String..., _ tag: Int){
print("[\(tag)] array: \(array)")
}
test3("Hello", "World", 1)
Is it possible to call the first method or the third method, without giving the second parameter a label?
Side note: Is this a language feature? Shouldn't the compiler have warn me? It currently tells me that I'm missing the second parameter when calling the function, but to me it seems that it's not even possible to provide this parameter.

swift func: i can't understand underscore as a parameter name that can compile

how to use underscore parameter
func test(currentName name: String, _: Int) {
print("aa\(name) abc");
//how to use _ parameter?
}
test(currentName:"aa", 3)
In Swift, functions have both parameter labels and parameter names. This is for clarity when using the functions. Think about a normal C function, it is declared as such:
string FunctionName(string firstName, string lastName)
Looking at the function declaration, it's easy to see what each parameter is. In this case, a firstName and a lastName. However when it is called in code, it's less apparent, particularly if the parameter values aren't self-describing. eg:
FunctionName("Neil","Armstrong") // Fairly obvious
FunctionName("Bo","Ng") // Not so obvious
In swift, parameters have both labels and names. Labels are there purely for clarity, so the code that calls the function can be read and understood more easily, without having to dive into its definition to fully understand it
let fullName = funcName(firstName: "Bo", lastName: "Ng")
In some cases, the parameter name is entirely unnecessary, eg:
let total = addTwoNumbers(1,2)
So the labels are optional, denoted by an underscore
func addTwoNumbers(_ firstVal:Int,_ secondVal:Int)
Generally speaking, you should use labels to make the functions you write clearer, unless you feel the parameters are entirely self-describing.
_ means when you call test function, you don't have to write the text before the second parameter test(currentName:"aa", 3)
if you declare your function like this:
func test(currentName name: String, secondParameter: Int) {
print("aa\(name) abc");
//how to use _ parameter?
}
then when you call test function, you must to call like this:
test(currentName:"aa", secondParameter: 3)
If you want to use second parameter of function but don't want to "name" it, you have to change signature of function to func test(currentName name: String, age _: Int) and then refer to second argument as age.
func test(currentName name: String, _ age: Int) {
print("Name: \(name), age: \(age)")
}
test(name: "Piter", 3)

Using overloaded functions as first class citizens

Suppose that we have several overloaded functions in one class:
func appendToABC(string s: String) -> String {
return "ABC \(s)"
}
func appendToABC(duplicatedString s: String) -> String {
return "ABC \(s)\(s)"
}
And we have some API that gets function as an argument:
func printString(function: (String) -> String) {
print(function("ASD"))
}
How can we pass one of appendToABC functions as an argument to a printString function?
I've thought about wrapping the function with a closure, but it doesn't look nice
printString { appendToABC(duplicatedString: $0) }
This is a known limitation in Swift. There is an open proposal to address it. Currently the only solution is a closure.
Note that this is true of many things in Swift. You also can't refer to properties directly as functions, even though they behave like functions. You must use a closure. And even some free functions cannot be directly passed (print is the most common example).

When to use the generic parameter clause

I'm new to generics in swift, and while reading some books, I came across something I don't understand. In generic functions, when is it appropriate to use the type parameter (the right after the function name)? and when is it inappropriate?
Here an example where it is not used (signature only; from standard library):
func sorted(isOrderedBefore: (T, T) -> Bool) -> Array<T>
Here's an example of where it is used (taken from a book I'm reading):
func emphasize<T>(inout array:[T], modification:(T) -> T) {
for i in 0 ..< array.count {
array[i] = modification(array[i])
}
}
I read Apple's swift language reference, section: Generic Parameters and Arguments. But it is still not clear to me. Thanks in advance for any insight.
 
In the first example, the generic parameter is coming from the type it is defined within. I believe it is declared within Array which already has the generic type T.
In the second example, the function itself is declaring the generic parameter. If I am not mistaken, this function is a global function. It is not already within a scope that defines a generic T.
It is only inappropriate to declare a new generic parameter in a function that obscures or tries to replace the one already declared in it's scope. For example, when extending an array, this would be inappropriate:
extension Array {
func myFunc<T>() {
}
}
Here we are defining a new T that is obscuring the original T that is already declared in the declaration of Array.
In all other circumstances where you want a generic type, you should be declaring it yourself.