Swift

Swift, Apple's new programming language for iOS and OS was introduced by Apple at WWDC 2014. It was build on the best of C and Objective-C and represent the future of Apple software development.

Here is my note about Apple's iBook, The Swift Programming Language.

First:

println("Hello, world")

Forget the ; and read the following for a swift tour.


Updated (Jul 15 2014) to adopt new Swift syntax after its first revision.


Simple value

let constant = 1
var variable = 1

Type of a variable (or constant) is infered by the compiler when providing a value. Type can be specified like this:

let explicitDouble: Double = 2

Value are never implicitly converted to another type.

var lineLabel = "Line " + String(3)

// Simpler way to include value in strings

lineLabel = "Line \(5)"

Arrays and dictionaries use brackets ([]).

var array = [
	"an element",
	"another element"
]
array += "last element"

var dictionary = [
	"a key": "an element",
	"another key": "another value"
]
dictionary["a key"] = "I'am an element"

// Empty  array or dictionary

let emptyArray = [String]()
let emptyDictionary = [String: String]()

Control flow

Parentheses around the condition or loop variable are optional. Braces around the body are required.

Condition in an if statement must be a boolean expression. ? can be used after the type of a value to mark it as optional.

var optionalInt: Int?

if !optionalInt {
	optionalInt = 8
}

Switches support any kind of data and wide variety of comparison operations. break are implicit.

let day = "Friday"

switch day {
case "Monday":
    "Not my favorite day"
case "Thursday", "Wednesday", "Tuesday":
    "When is the weekend ?"
case let d where d.uppercaseString == "FRIDAY":
    "Weekend is coming soon..."
case "Saturday", "Sunday":
    "😎"
default:
    "Not a day"
}

Functions

func addOneTo(number: Int) -> Int {
    return number + 1
}

Function can return multiple values using tuples.

func prices() -> (Double, Double, Double) {
    return (0.0, 0.99, 1.29)
}

Function can take a variable number of arguments.

func sumOf(numbers: Int...) -> Int {
    var sum = 0
    for number in numbers {
        sum += number
    }
    return sum
}

Function can be nested.

Functions accept functions as arguments and return value.

func getMyFunc(function: (Int, Int) -> Int) -> ((Int, Int) -> Int) {
    return function
}

Closures

var numbers = [13, 21, 34, 55]

numbers.map({
    (number: Int) -> Int in
    return number * 2
})
numbers.map({ number in number * 2 })
numbers.map({ $0 * 2 })
numbers.map() { $0 * 2 }
numbers.map { $0 * 2 }

// [26, 42, 68, 110]

Objects and Classes

Methods that override the superclass's implementation are mark with override.

Methods can specify a second name for parameters, which is used inside the method.

class Counter {
    var count: Int

    init() {
        count = 0
    }
    func incrementBy(amount: Int, numberOfTimes times: Int) {
        count += amount * times
    }
}

var counter = Counter()
counter.incrementBy(2, numberOfTimes: 1_024)

Enumerations and structures

Enumerations can have methods associated with them.

An instance of an enumeration member can have values associated with the instance:

enum ServerResponse {
    case Result(String, String)
    case Error(String)
}
ServerResponse.Result("200", "OK")

Structures support many of the same behaviors as classes, including methods and initializers. Structures are always passed by copy while classes are passed by reference.

struct Point {
    var x: Int
    var y: Int

    init(x: Int, y: Int) {
        self.x = x
        self.y = y
    }
    func description() -> String {
        return "Point: { x: \(x), y: \(y) }"
    }
}

let p = Point(x:0, y:0)

Protocols and Extensions

Classes, enumerations, and structs can adopt protocols.

protocol PrintProtocol {
    var description: String { get }

    mutating func print()
}

class PrintableClass: PrintProtocol {
    var description: String = "Printable class"

    func print() {
        println(description)
    }
}

Enumerations and structures need mutating keyword to mark a method that modifies the structure.

struct PrintableStruct: PrintProtocol {
    var description: String = "Printable struct"

    mutating func print() {
        println(description)
    }
}

Extensions are used to add functionality to an existing type, such as methods and computed properties. Extensions can be used to add protocol conformance to a type.

extension Double {
    func modulus() -> Double {
        return abs(self)
    }
}

Generics

Functions, methods, classes, enumerations and structures can be generic.

func repeat<T>(item: T, times: Int) -> [T] {
    var result = [T]()
    for i in 0 ..< times {
        result += item
    }
    return result
}
repeat("knock", 2)

Type can require to implement protocol, to be the same as an other type or to have a particular superclass.

func commonElements <T, U where T: Sequence, U: Sequence,
    T.GeneratorType.Element: Equatable,
    T.GeneratorType.Element == U.GeneratorType.Element>
    (lhs: T, rhs: U) -> [T.GeneratorType.Element] {
        var result = Array<T.GeneratorType.Element>()
        for lhsItem in lhs {
            for rhsItem in rhs {
                if lhsItem == rhsItem {
                    result += rhsItem
                }
            }
        }
        return result
}
commonElements([1, 2, 3, 4], [2, 4, 6])

It's a quick tour of Swift and there is so much to write...