How to access an anonymous parameter within a method? - swift

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).

Related

Why are argument names required for function calls, and not allowed for functions assigned to variables?

If I have the following code, why am I not required to use the argument names in the function call and instead an error is thrown when I attempt to add them?
func foo(bar: Any) {}
var faz = foo
foo(1) // Missing argument label 'bar:' in call
foo(bar: 1)
faz(1)
faz(bar: 1) // Extraneous argument label 'bar:' in call
When you assign your method as closure, you just assign method's types of paramters and return type, so type of your closure is actually (Types of arguments) -> Return type
In your specific case: (Any) -> Void
As you can see, this closure doesn't have names for arguments and you can't add them. So adding argument label when you call your closure won't work.
But, you can name parameter which closure takes when you declare it and then you can work with it inside closure scope ... similar to declaring function
faz = { bar in
... // you can work with bar of type `Any`
}

what is the context in swift?

I am new in swift . let' try to understand closures
declare a function like closures:
let sayHello = {
return "hello"
}
unable to infer closures return type of current context ()->()
My question is here what is the context ?
let sayHello : String = {
return "hello"
}
Function produce expected type of "string" , did you mean to call it with ()
honestly i did not understand this error ? anyone help me to understand and why need to specify this one ()
however . this is working fine and without error it is called closures
let sayHello : String = {
return "hello"
}()
thank you
The context the error message refers to means the initialization statement for the closure, along with its surrounding.
Swift can often infer (figure out from things that it already knows) the type of closure, without requiring you to specify it explicitly.
For example, if you are calling a function that takes a closure taking an Int as its argument, Swift figures out that the type of your closure's argument must be an Int. Similarly, if your closure returns a captured local variable of type String, Swift does not need you to specify the return type, because it figures it must be String as well.
None of this works when you create closures for future use, and assign them to a variable. In situations like that you need to tell Swift what kind of closure you are creating:
let sayHello : ()->String = {
return "hello"
}
Now you have a variable sayHello of type "a closure that takes no arguments and returns a String" (i.e. ()->String closure). You can call it later to say hello:
let hello = sayHello()
Note: Your example that "worked" also defined a closure. However, the closure was used immediately after its definition, and then discarded.

Difference between two simple functions in 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.

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.

Swift "with" keyword

What's the purpose of "with" keyword in Swift? So far I have found that the keyword can be used if you need to override an existing global function, such as toDebugString.
// without "with" you get "Ambiguous use of 'toDebugString'" error
func toDebugString<T>(with x: T) -> String
{
return ""
}
toDebugString("t")
with is not a keyword - it's just an external parameter identifier. This works as well:
func toDebugString<T>(whatever x: T) -> String
Since the toDebugString<T>(x: T) function is already defined, by using an external parameter you are creating an overload: same function name, but different parameters. In this case the parameter is the same, but identified with an external name, and in swift that makes it a method with a different signature, hence an overload.
To prove that, paste this in a playground:
func toDebugString<T>(# x: T) -> String {
return "overload"
}
toDebugString(x: "t") // Prints "overload"
toDebugString("t") // Prints "t"
The first calls your overloaded implementation, whereas the second uses the existing function
Suggested reading: Function Parameter Names