Functions in Swfit 3.0


As you have seen the previous post on Protocol, NSBlockOperation, Range Operators, Extension. Here you go with the new topic as Function in Swift 3.0.1 with Xcode 8.1. It will include detailed explanation about it.

According to Apple’s Swift Programming Language Book:


Methods are functions that are associated with a particular type. Classes, structures, and enumerations can all define instance methods, which encapsulate specific tasks and functionality for working with an instance of a given type. Classes, structures, and enumerations can also define type methods, which are associated with the type itself. Type methods are similar to class methods in Objective-C.

Functions

A function contains some lines code which performs a specific task. You need to a name function, which explains what it does, call it whenever you need it.


Defining and Calling Functions:

Defining function - 

func wishBday(person: String) -> String {

let wishes= "Hello, " + person + "!"

return wishes

}

The above function takes a person an return string as wishes.  Func keyword is used to create function the function name (meaningful) and then return type of the function and with ‘{‘ & ‘ }’’ write the code what you want to do.

print(wishBday(person: "Anna"))

Function Parameters and Return Values

Function parameters and return values are extremely flexible in Swift.

Functions Without Parameters:

    func wishBday() -> String {

    return "Hello,Happy Birthday!!!"

    }

As you can see there is no parameter passing in above function.

Functions With Multiple Parameters:

func wishBdayBoth(person1: String, person2: String) -> String {
    let wishes = "Happy Birthday," + person1 + " and " + person2 + " to both."
    return wishes
}

calling above function  is like
wishBdayBoth(person1: "Sanoj", person2: "Vartika")

Functions Without Return Values:

func wishBdayBoth(person1: String, person2: String){
    let wishes = "Happy Birthday," + person1 + " and " + person2 + " to both."
    print(wishes)
}

NOTE
Strictly speaking, this version of the wishBdayBoth (person1: person2:) function does still return a value, even though no return value is defined. Functions without a defined return type return a special value of type Void. This is simply an empty tuple, which is written as ().

Functions with Multiple Return Values

We use tuple type as the return type for multiple return values from the function as a part of one compound return value.

func wishBdayBoth(lang1: String, lang2: String) ->(String,String,String){
    let msg = "Happy Coding, Learning" + lang1+ "" + lang2+ " together."
    return (lang1, lang2, msg)
}

wishBdayBoth(lang1: "Swift", lang2: "Lang")

This could be used another way as well suppose when sorting any array and want to get the min and max number from that function then you return min and max together in a tuple as a return value.

Note that the tuple’s members do not need to be named at the point that the tuple is returned from the function, because their names are already specified as part of the function’s return type.

Optional Tuple Return Types:

If a tuple to set for function as a return value and function has potential to have no value to returned for the entire tuple, you can use optional tuple return type to reflect the fact that the entire tuple can be nil.

You can write optional tuple by adding a ‘?’ after the tuple declaration. So suppose (String, String,String)?

NOTE
An optional tuple type such as (Int, Int)? is different from a tuple that contains optional types such as (Int?, Int?). With an optional tuple type, the entire tuple is optional, not just each individual value within the tuple.

So we added checks for an empty string that time we can not form a message so we are returning nil as an optional tuple value.

func wishBdayBoth(lang1: String, lang2: String) ->(String,String,String)?{
   
    if lang1.isEmpty && lang2.isEmpty{
        return nil
    }
    let msg = "Happy Coding, Learning" + lang1 + "and" + lang2 + ""
    return (lang1, lang2, msg)
}
wishBdayBoth(lang1: "",lang2:"") //return nil

Function Argument Labels and Parameter Names:

Each function parameter has both an argument label and a parameter name. The argument label is used when calling the function; each argument is written in the function call with its argument label before it. The parameter name is used in the implementation of the function. By default, parameters use their parameter name as their argument label.

func wishBday(person: String) -> String {

let wishes= "Hello, " + person + "!"

return wishes

}


Above function has argument label as person.
All parameters must have unique names. Unique argument labels help make your code more readable.

Specifying Argument Labels:

You write an argument label before the parameter name, separated by a space:
func someFunction(PersonToWishForBirthdayArgumentLabel person2: String) {
    print("Happy Birthday," + person2 + "")
}
someFunction(PersonToWishForBirthdayArgumentLabel: "Sanoj"

Omitting Argument Labels

If you do not want to give the argument label then (_) in place of that.

func someFunction(_ person2: String) {
    print("Happy Birthday," + person2 + "")
}
someFunction(_: "Sanoj")

Default Parameter Values:

You can define a default value for any parameter in a function by assigning a value to the parameter after that parameter’s type. If a default value is defined, you can omit that parameter when calling the function.

func someFunction(person2:String = "Swift") {
    print("Happy Birthday," + person2 + "")
}
someFunction()

//print  "Happy Birthday,Swift"

Variadic Parameters:

variadic parameter accepts zero or more values of a specified type. It specifies that parameter can be passed as a varying number of input values when the function is called. It can be used as three-period dots (…) after the parameter type name.

The values passed to a variadic parameter are made available within the function’s body as an array of the appropriate type
func sum(_ numbers: Double...) -> Double {
    var total: Double = 0
    for number in numbers {
        total += number
    }
    return total
}

sum(1, 2, 3, 4, 5)
NOTE
A function may have at most one variadic parameter.

In-Out Parameters:

Function parameters are constants by default.  If you try to change the value of the parameter with in the body of the function, you will end up with compile time error. If you want a function to modify a parameter’s value, and you want those changes to persist after the function call has ended, define that parameter as an in-out parameter instead.

You write an in-out parameter by placing the inout keyword right before a parameter’s type. You can only pass a variable as the argument for an in-out parameter. You cannot pass a constant or a literal value as the argument because constants and literals cannot be modified.

You can add ‘&’  before the variable name when you pass it as an argument to an in-out parameter, to indicate that it can be modified by the function.

NOTE                                                                                                               
In-out parameters cannot have default values, and variadic parameters cannot be marked as inout.

func swapTwoInts(_ a: inout Int, _ b: inout Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}

var firstNumber = 3
var secondNumber = 107
swapTwoInts(&firstNumber, &secondNumber)
print("someInt is now \(firstNumber), and anotherInt is now \(secondNumber)")
// Prints "firstNumber is now 107, and secondNumber is now 3"

NOTE
In-out parameters are not the same as returning a value from a function. The example swapTwoInts above does not define a return type or return a value, but it still modifies the values of firstNumber and secondNumber. In-out parameters are an alternative way for a function to have an effect outside of the scope of its function body.

Function Types:

Every function has a specific function type, made up of the parameter types and the return type of the function.

func addInt(_ a: Int, _ b: Int) -> Int {
    return a + b
}

This function is (Int, Int) -> Int. This can be read as:
“A function type that has two parameters, both of type Int, and that returns a value of type Int.”


Using Function Types


You use function types just like any other types in Swift. For example, you can define a constant or variable to be of a function type and assign an appropriate function to that variable:

var mathFunction: (Int, Int) -> Int = addInt 
This can be read as:
“Define a variable called mathFunction, which has a type of ‘a function that takes two Int values, and returns an Int value.’ 
print("Result: \(mathFunction(2, 3))") //print 5
// mathFunction is inferred to be of type (Int, Int) -> Int


Function Types as Parameter Types

 You can use a function type such as (Int, Int) -> Int as a parameter type for another function.

func printMathResult(_ mathFunction: (Int, Int) -> Int, _ a: Int, _ b: Int) {
    print("Result: \(mathFunction(a, b))")
}

printMathResult(addInt, 3, 5)

The function defines a function called printMathResult (_:_:_:), which includes three parameters. The First is addInt function of type (Int Int)->Int. We can pass any function of the same type as the first parameter.The Other two parameter are Int type which will be used to an input parameter for the first function as a parameter.

Function Types as Return Types


You can use a function type as the return type of another function. You do this by writing a complete function type immediately after the return arrow (->) of the returning function.

func myFuncThatReturnsAFunc() -> (String,String) -> String {
    return {
        firstName, lastName in
        return "Concatenated String " + firstName + " " + lastName
    }
}

let returnedFunction = myFuncThatReturnsAFunc()

returnedFunction("Swift","Coding") // "Concatenated String Swift Coding"

 To make this more readable, you can of course use type-aliasing for your return function:
typealias returnedFunctionType = (String,String) -> String

func myFuncThatReturnsAFunc() -> returnedFunctionType {
    return {
        firstName, lastName in
        return "Concatenated String " + firstName + " " + lastName
    }
}

let returnedFunction = myFuncThatReturnsAFunc()
returnedFunction("Swift","Coding") // "Concatenated String Swift Coding"


Nested Functions:

You can also define functions inside the bodies of other functions, known as nested functions. Nested functions are hidden from the outside world by default, but can still be called and used by their enclosing function.

func myFunction(someNumber: Int) {
   
    func increment(someNumber: Int) -> Int {
        return someNumber + 10
    }
   
    let incrementedNumber = increment(someNumber: someNumber)
    print("The incremented number is \(incrementedNumber)")
}

myFunction(someNumber: 10)
// The incremented number is 15
   
Access Controls:
Swift has three levels of access controls:

·          Public access enables entities to be used within any source file from their defining module, and also in a source file from another module that imports the defining module. You typically use public access when specifying the public interface to a framework.
·         Internal access enables entities to be used within any source file from their defining module, but not in any source file outside of that module. You typically use internal access when defining an app’s or a framework’s internal structure.
·         Private access restricts the use of an entity to its own defining source file. Use private access to hide the implementation details of a specific piece of functionality.

By default, every function and variable are internal — if you want to change that, you have to use the private or public keyword in front of every single method and variable:

public func myPublicFunc() {}

func myInternalFunc() {  }

private func myPrivateFunc() {  }


Here Just giving small details of Function Access Control.. I will be posting a complete detailed blog on Access Control in future.
As swift is changing frequently so better to keep updated with latest uses and syntax.
Keep posting your valuable comments and suggestion.

Happy Swifting : ) Happy Coding : )

Comments

Popular posts from this blog

Copy Vs Mutable Copy in iOS

How to Disable iOS/iPad App availability on Mac Store, Silicon?