The second installment of SWIFT Programming language intro is about Function, closures and Enums

Functions

Function are implemented with keyword func

func funcName (arg1: Type, arg2: Type) -> ReturnType{
}

If function does not return anything remove the ReturnType

Function Parameters
External Parameter Name

Function can have external parameter name (fancy name for named parameters?)

func funcName (named1 arg1: Type, named2 arg2: Type) -> ReturnType{
}

//If external name = arg name, prefix the arg with #
func funcName (#named1: Type, #named2: Type) -> ReturnType{
}

//when called
funcName(named1:1, named2: 1)
Default Parameter

Default parameter are the last params a method accepts

//If no param is passed, name will be set to A
func funcName (name: String = "A"){
}
Variadic Parameter

A parameter that accepts zero or more values, they are made available as an Array inside the function

func funcName (params: String...){
    //params is a String[] 
}
Variable function paramater

Function params are by default constants, to make them variables add var before the param

In-Out parameter

To define an inout parameter use inout before the parameter name

func funcName (inout params: String...){
    //changes to params will reflect after func call
}

//Calling
funcName(&someVar) //Address or pointer notion
Function Type

Each function has a Type that is made up of its parameters and return value

func test(a: Int) -> Int {} //type (Int) -> ()Int)
func test(a: String) {} //type (String) -> ()

Function types can be used as any other type

//As var type
var x: () -> Int
var y: Int -> String

//Passed as a parameter, f accepts a function
func f(a: (Int) -> (Int)) {}
//As a return type, f returns a function
func f() -> (String) -> (String) {}
Nested Functions

A function can be defined inside another function, it will be scoped locally to the function its defined in.


Closures

Closures are self-contained blocks of functionality that can be passed around and used in your code
Functions are special case of closures

func myFunc(i: Int) -> String {}
var myClosure: Int -> String = { i in }

In the above example myFunc and myClosure has the same type of (Int) -> (String)

Closure Expression
Closure Function Expression

Closure can be defined as a function,

func f(){}
var c = f
Closure Function Expression

Closure general syntax is as follows

var closure = { (argsLikeInFuncion) -> ReturnType in
  //Code
}

//Call
closure(args)

Closure types can be inferred from the context, Also note in the example if the last parameter is a closure, it could be written outside the ) for a better syntax

Closure Inferring Types

In the bellow examples the param types are inferred we only need parameter names

sort(arr) { s1,s2 in //We name the parameters
    //Do Stuff
}

var myClosure: Int -> String = { i in }
//i and return Types are inferred

In order to omit the parameter names too, we could use the arguments short hand names $0,$1, $2

sort(arr) {
    //You can omit the section before in    
    //We can access the parameters as $0 and $1
}

var myClosure: Int -> String = { /* use $0 inside */ }
Trailing Closures

If a function accepts a closure as its last parameter, you can write the closure expression outside the function parentheses

func f(a: Int, closure: ()->()) {}

//Call it
f (1) {
    //Closure code
}

//If function has only 1 argument you can remove the ()
f2 {
    //Closure code
}

Enumerations

An enumeration defines a common type for a group of related values and enables you to work with those values in a type-safe way within your code.

enum SomeEnumeration {
  // enumeration definition goes here
  case C1
  case C2, C3, C$
}

var a = SomeEnumeration.C1
//Once inferred
a = .C2
Enum Associated Values

Enum can be associated with values

enum MyEnum {
  case Case1(Int)
  case Case2(String)
}

Enum of Case1/Case2 will have a Int/String associated with their types

switch(m1) {
    //Get associated value
    case let .Case1(value):
        var w = value
}

More Stuff: