Parameter passing in Swift [duplicate] - ios

This question already has answers here:
When are argument labels required in Swift?
(6 answers)
Closed 6 years ago.
I have the following piece of code written in swift:
func hai(greeting: String, times: Int) -> String {
return "You are greeted + \(greeting) + \(times) times "
}
hai ("Hello", times: 3)
When I call the function hai, if I call it the following way hai("hello", 3) it throws an error and forces me to call the way it was mentioned above.
Can someone please explain why this should be the case? Thanks, I am new to IOS programming.

Each function parameter in Swift has two names - an internal and an external one. When you define function signature the way you did, the external parameter name of times is the same as its internal name. You can tell Swift that you do not want an external name by placing _ in the external name position:
func hai(greeting: String, _ times: Int) -> String
// ^
Learn more about internal/external parameter names in the Swift 2.2 Programming Language Guide.

Related

Swift gives syntax error while func calling

I am new in swift and I am following apples doc for studying it.
apple doc
func greet(name: String, day: String) -> String {
return "Hello \(name), today is \(day)."
}
greet("Bob", day: "Tuesday")
I just copy above code from apple doc and try to run in playground but in last line its gives me syntax error and telling that remove day: in that.
When I am remove day: in fun calling its run perfectly
greet("Bob", "Tuesday")
Is there any mistake in apple doc or I am doing something wrong?
Naming the parameters of a function works different, depending on where the function is defined (and again different on initializers)
The way, you defined the function is global, outside of a class. In this case the function call does not name parameters.
If you would define the function inside a class, your first try would work perfectly fine. In functions inside a class (methods) you name the parameters except the first one. If you would like to have the first name, too, you would use
func greet(#firstParameter: String, secondParameter: String) ...
And to complete all that, initializers need all parameters named. Even the first one and even without the #.
Does all that sound a bit confusing? Well, Apple had the same opinion and according to what was said on WWDC 2015 they change the behavior in Swift 2 and make it more consistent.
These are Swift "functions" not "methods". They do not need parameter names. You can still add them in the declaration for readability, but you cannot use it while calling.
On the other hand, class "methods" are named and work as you expected.
If you still need named parameters while calling, try this:
func greet(name: String, #day: String) -> String {
return "Hello \(name), today is \(day)."
}
greet("Bob", day: "Tuesday")
This will give you expected results.
Find this in documentation:
However, these parameter names are only used within the body of the
function itself, and cannot be used when calling the function. These
kinds of parameter names are known as local parameter names, because
they are only available for use within the function’s body.
A note on methods and functions:
Simply put, methods belong to a class. Functions don't. From documentation:
Functions are self-contained chunks of code that perform a specific
task. You give a function a name that identifies what it does, and
this name is used to “call” the function to perform its task when
needed.
Note that Swift 2.0 makes no difference between method calls and function calls, so in Swift 2.0, your way is valid.
In function:
func greet(name: String, day: String) -> String {
}
"name" and "day" are variables not the label as in Obj C. You can write "day" as label as:
func greet(name: String, day day: String) -> String {
}
You have to understand that a new language like Swift is bound to change. This is one of those changes, it was introduced during WWDC 2015.
Apple has unified how you define and call functions and methods, so that the behaviour is the same. They completely removed the # from func definitions and made it a requirement that the name of the 1st argument of func be included in the name, and the all other arguments have the option of either having a name, or not.
These are examples of valid func declarations in Swift 2.0, which is to be released with Xcode 7 and iOS 9.
func moveShapeToPosition(position: CGPoint, andScaleBy scale: CGFloat)
func moveShapeToPosition(position: CGPoint, scale: CGFloat)
func moveShapeToPosition(position: CGPoint, _ scale: CGFloat)
And to call them.
moveShapeToPosition(CGPoint(x: 0, y: 0), andScaleBy: 1)
moveShapeToPosition(CGPoint(x: 0, y: 0), scale: 1)
moveShapeToPosition(CGPoint(x: 0, y: 0), 1)
It's the version of Swift made the difference.
I run the demo in Xcode 7.0 Beta, it works perfectly.
Besides, when I try to call greet like greet("Bob", "Tuesday") in Xcode 7.0 Beta, it gives me the error that the day: is missing.
However, when I run it in the Xcode 6.4, it complaints the same as yours.
In Swift, functions and methods are different. you can find detailed answer here.
You must be created function which means you may have created it inside Viewdidload(it's my guess). So you can't specifically give the function parameter name.
if you've created method (outside the viewdidload) then you can call like you've tried
greet("Bob", day: "Tuesday")
or
Check for Shorthand External Parameter Names for external parameter names.

Forced to use parameter names, but only some of them [duplicate]

This question already has answers here:
Function Parameter Names don't behave according to documentation
(2 answers)
Closed 7 years ago.
I'm new to Swift and I've read the Swift Function Documentation and as far as I understand a function has to be built this way:
func funcName(param1:Type, param2:Type) -> Return {
//Whatever istructions
}
And has to be called this way:
funcName(1, 2);
Very easy, and here is from the original Apple documentation:
func halfOpenRangeLength(start: Int, end: Int) -> Int {
return end - start
}
println(halfOpenRangeLength(1, 10))
// prints "9"
So in this last example when calling the halfOpenRangeLength function I don't have to specify the name of the parameters (start and end).
So I did my function in XCode:
func assegnaRisposte(uno:String, due:String, tre:String, quattro:String){
button1.setTitle(uno, forState: UIControlState.Normal)
button2.setTitle(due, forState: UIControlState.Normal)
button3.setTitle(tre, forState: UIControlState.Normal)
button4.setTitle(quattro, forState: UIControlState.Normal)
}
But when I call it this way I get the error Missing argument lables 'due:tre:quattro:' in call:
assegnaRisposte("Davide", "Andrea", "Sergio", "Roberto")
And the XCode fix imposes me to do it this way:
assegnaRisposte("Davide", due: tre: "Andrea", "Sergio", quattro: "Roberto")
So I'M FORCED to place 3 of the parameter names. If I place the first parameter (uno) it throws an error, so I have to put ONLY due, tre and quattro
As far as I read I can specify the parameter names placing a dash in front of the parameter, and also, I'm not FORCED to use them.
Can somebody explain me why is this?
There is a difference between functions and methods in Swift in naming, basically:
the default naming of functions is that there are no external
parameter names.
the default naming for methods is that there are external
parameter names expect the first parameter.
And you can read about the differences between methods and functions here or here.
Updated:
If you don't want to use external parameter names, you should declare your method like:
func assegnaRisposte(uno:String, _ due:String, _ tre:String, _ quattro:String){
...
}
Check out this section from Apple's The Swift Programming Language book:
Local and External Parameter Names for Methods
The default behavior of local names and external names is different
for functions and methods.
Swift gives the first parameter name in a method a local parameter
name by default, and gives the second and subsequent parameter names
both local and external parameter names by default.

syntax error for function-- missing parameter

I am learning swift from apple book. while writing code in xcode, I am getting error that parameter missing form function.
according to Apple code should be
func halfOpenRangeLength(start: Int, end: Int) -> Int {
return end - start
}
while calling this function :
println(halfOpenRangeLength(1, 10)) // According to Apple.
but when I type above line it says insert end
so this statement changes to
println(halfOpenRangeLength(1, end:10))
why this happens?
Thanks
Swift always gives the first parameter a local parameter name and no external parameter name. This means you don't need to call it when you use the method.
After that, every parameter is given both a local and external parameter name. This is meant to be for clarity's sake. As Leonardo said, you can avoid having to name the second parameter by placing an underscore (_) in front of the parameter name.
In case you ever want to, you can also provide an external parameter name for the first variable by placing a hashtag (#) in front of the parameter name.
You can check out more information about this in Apple's Swift Documentation: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Methods.html
use this instead I've checked it and it works
func halfOpenRangeLength(start: Int, end: Int) -> Int {
return end - start
}
println("\(halfOpenRangeLength(1, 10))")
If you don't want it to require the argument name you just need to add _ in front of it and it will not bug you about it anymore:
vv
func halfOpenRangeLength(start: Int, _ end: Int) -> Int {
Swift gives automatic external names to parameters following these rules:
global functions: no automatic external names
class/struct/enum methods: automatic external names for all parameters but the first
initializers: automatic external names for all parameters
That said, if it doesn't work in your case, requiring you to specify the external name for the 2nd parameter, than it probably means you've declared that function as a class or struct method, not as a global function.

Function not working in Swift

So I've been trying to learn a bit of Swift and I've been looking at functions with return types. I added this function, and it should work, but I still get the error "Could not find member 'convertFromStringInterpolationSegment.' I've looked at other stack overflow questions and have tried to apply their answers, but to no avail. Some help would be greatly appreciated.
func getGasPrices2(price1: Double, price2:Double, price3:Double)
{
return "The prices are \(String(price1)), \(String(price2)), \(String(price3))."
}
getGasPrices2(3.59, 3.69, 3.79)
You forgot to declare a return type. Since you want to return a String, the function needs to declare that:
func getGasPrices2(price1: Double, price2:Double, price3:Double) -> (String)
I'm sure that Apple will work on these wonderful error messages. :)
As Alvin stated, you were simply missing the return type
-> (String)
...in the function's declaration.
I find myself doing the same thing, forgetting the return type at the end, as I'm still getting used to writing in Swift while having the function-type-declaration-first of Objective-C habit
...
Basically your function in Swift...
func getGasPrices2(price1: Double, price2:Double, price3:Double) -> (String)
...is equivalent* to
-(NSString*)getGasPrices2: (double)price1 price2:(double)price2 price3:(double)price3
...in Objective-C*
*Strings in Swift aren't exactly the same as NSStrings but both functions would be able to accomplish what you are looking to do; one in Objective-C, the other in Swift (as long as you make sure to actually return a String/NSString at the end :-)

Swift : missing argument label 'xxx' in call

func say(name:String, msg:String) {
println("\(name) say \(msg)")
}
say("Henry","Hi,Swift") <---- error because missing argument label 'msg' in call
I need to use
say("Henry",msg:"Hi,Swift")
Why ? If I put more than two var in func so that I need to write var name instead of first var when I call this func
It's really trouble, and I don't see any explain in iBook Swift tutorial.
One possible reason is that it is actually a method. Methods are very sneaky, they look just like regular functions, but they don't act the same way, let's look at this:
func funFunction(someArg: Int, someOtherArg: Int) {
println("funFunction: \(someArg) : \(someOtherArg)")
}
// No external parameter
funFunction(1, 4)
func externalParamFunction(externalOne internalOne: Int, externalTwo internalTwo: Int) {
println("externalParamFunction: \(internalOne) : \(internalTwo)")
}
// Requires external parameters
externalParamFunction(externalOne: 1, externalTwo: 4)
func externalInternalShared(#paramOne: Int, #paramTwo: Int) {
println("externalInternalShared: \(paramOne) : \(paramTwo)")
}
// The '#' basically says, you want your internal and external names to be the same
// Note that there's been an update in Swift 2 and the above function would have to be written as:
func externalInternalShared(paramOne paramOne: Int, #paramTwo: Int) {
print("externalInternalShared: \(paramOne) : \(paramTwo)")
}
externalInternalShared(paramOne: 1, paramTwo: 4)
Now here's the fun part, declare a function inside of a class and it's no longer a function ... it's a method
class SomeClass {
func someClassFunctionWithParamOne(paramOne: Int, paramTwo: Int) {
println("someClassFunction: \(paramOne) : \(paramTwo)")
}
}
var someInstance = SomeClass()
someInstance.someClassFunctionWithParamOne(1, paramTwo: 4)
This is part of the design of behavior for methods
Apple Docs:
Specifically, Swift gives the first parameter name in a method a local parameter name by default, and gives the second and subsequent parameter names both local and external parameter names by default. This convention matches the typical naming and calling convention you will be familiar with from writing Objective-C methods, and makes for expressive method calls without the need to qualify your parameter names.
Notice the autocomplete:
This is simply an influence of the Objective-C language. When calling a method, the first parameter of a method does not need to be explicitly labelled (as in Objective-C it is effectively 'labelled' by the name of the method). However all following parameters DO need a name to identify them. They may also take an (optional) local name for use inside the method itself (see Jiaaro's link in the comments above).
Simple:
Wrong call function syntax's( its not same in c/c++/java/c#)
Incorrect:
say("Henry")
Correct:
say(name:"Henry")
PS: You must always! add "name function parameter" before value.
Swift 3.0 update:
In swift 3.0, methods with one param name per inputs are required to have that param name as part of the function call. So if you define the function like this
func say(name:String, msg:String) {
print("\(name) say \(msg)")
}
Your function call will have to be like this
self.say(name: "Henry",msg: "Hi,Swift")
If you want to have English like readable function labels but do not want to change input param name, you can add the label in front of the parameter names, like this
func say(somethingBy name:String, whoIsActuallySaying msg:String) {
print("\(name) say \(msg)")
}
Then calling it like this
self.say(somethingBy: "Henry",whoIsActuallySaying: "Hi,Swift")
This is a quirk in the compiler. Functions (which are not members of a class) and class methods have different default behavior with regards to named parameters. This is consistent with the behavior of named parameters in objective-C (but makes no sense for someone new to swift with no experience with objective-C).
Here's what the language reference has to say about named parameters for functions (specifically parameters where an external name for the parameter is not given, and the parameter does not have a default value)
However, these parameter names are only used within the body of the
function itself, and cannot be used when calling the function. These
kinds of parameter names are known as local parameter names, because
they are only available for use within the function’s body.
For information about class methods, see Logan's answer.
Please find the small code for understanding in swift 3+.
func sumInt(a:Int,b:Int){
print(a+b) // Displays 3 here
}
sumInt(a: 1, b: 2) // not like in other languages

Resources