Monday, January 12, 2015

The Swift Programming Language Note 1 (From the Basics to Functions)

The Swift Programming Language Note 1 (From the Basics to Functions)
1. variable
declare constants with the let keyword and variables with the var keyword.
let maximumNumberOfLoginAttempts = 10
var currentLoginAttempt = 0
You can declare multiple constants or multiple variables on a single line, separated by commas:
var x = 0.0, y = 0.0, z = 0.0
You can provide a type annotation when you declare a constant or variable.
Write a type annotation by placing a colon after the constant or variable name, followed by a space, followed by the name of the type to use.
var welcomeMessage: String
var red, green, blue: Double
It is rare that you need to write type annotations in practice.
You can print the current value of a constant or variable with the println function:
println(friendlyWelcome)
println("The current value of friendlyWelcome is \(friendlyWelcome)")

Swift provides signed and unsigned integers in 8, 16, 32, and 64 bit forms.
In most cases, you don’t need to pick a specific size of integer to use in your code. Swift provides an additional integer type, Int, which
has the same size as the current platform’s native word size:
On a 32-bit platform, Int is the same size as Int32.
On a 64-bit platform, Int is the same size as Int64.

Double represents a 64-bit floating-point number. Use it when floating-point values must be very large or particularly precise.
Float represents a 32-bit floating-point number. Use it when floating-point values do not require 64-bit precision.
Double has a precision of at least 15 decimal digits, whereas the precision of Float can be as little as 6 decimal digits. The appropriate floating-point
type to use depends on the nature and range of values you need to work with in your code.
Swift always chooses Double (rather than Float) when inferring the type of floating-point numbers.

Numeric literals can contain extra formatting to make them easier to read. Both integers and floats can be padded with extra
zeroes and can contain underscores to help with readability.
let justOverOneMillion = 1_000_000.000_000_1

Tuples group multiple values into a single compound value.
let http404Error = (404, "Not Found")
// http404Error is of type (Int, String), and equals (404, "Not Found")
let (statusCode, statusMessage) = http404Error
println("The status code is \(statusCode)")
// prints "The status code is 404"
println("The status message is \(statusMessage)")
// prints "The status message is Not Found"
If you only need some of the tuple’s values, ignore parts of the tuple with an underscore (_) when you decompose the tuple:
let (justTheStatusCode, _) = http404Error
Alternatively, access the individual element values in a tuple using index numbers starting at zero:
println("The status code is \(http404Error.0)")
// prints "The status code is 404"
Tuples are useful for temporary groups of related values. They are not suited to the creation of complex data structures. If your data structure
is likely to persist beyond a temporary scope, model it as a class or structure, rather than as a tuple.

You use optionals in situations where a value may be absent.
let possibleNumber = "123"
let convertedNumber = possibleNumber.toInt()
// convertedNumber is inferred to be of type "Int?", or "optional Int"
You set an optional variable to a valueless state by assigning it the special value nil:
var serverResponseCode: Int? = 404
// serverResponseCode contains an actual Int value of 404
serverResponseCode = nil
// serverResponseCode now contains no value
nil cannot be used with nonoptional constants and variables. If a constant or variable in your code needs to work with the
absence of a value under certain conditions, always declare it as an optional value of the appropriate type.
If you define an optional constant or variable without providing a default value, the constant or variable is automatically set to nil for you:
var surveyAnswer: String?
// surveyAnswer is automatically set to nil
Once you’re sure that the optional does contain a value, you can access its underlying value by adding an exclamation mark (!) to the end of the
optional’s name. The exclamation mark effectively says, “I know that this optional definitely has a value; please use it.” This is known as forced
unwrapping of the optional’s value:
if convertedNumber != nil {
    println("convertedNumber has an integer value of \(convertedNumber!).")
}
// prints "convertedNumber has an integer value of 123."
Trying to use ! to access a non-existent optional value triggers a runtime error. Always make sure that an optional contains a non-nil value
before using ! to force-unwrap its value.

if let actualNumber = possibleNumber.toInt() {
    println("\'\(possibleNumber)\' has an integer value of \(actualNumber)")
} else {
    println("\'\(possibleNumber)\' could not be converted to an integer")
}
// prints "'123' has an integer value of 123"


2. Semicolons
Unlike many other languages, Swift does not require you to write a semicolon (;) after each statement in your code, although you can do so if you wish.
Semicolons are required, however, if you want to write multiple separate statements on a single line:
let cat = "🐱"; println(cat)

3. Assertions
If the condition evaluates to true, code execution continues as usual; if the condition evaluates to false, code execution ends, and your app is terminated.
let age = -3
assert(age >= 0, "A person's age cannot be less than zero")
Use an assertion whenever a condition has the potential to be false, but must definitely be true in order for your code to continue execution.

4. Basic Operators
let (x, y) = (1, 2)
// x is equal to 1, and y is equal to 2

Swift’s remainder operator can also operate on floating-point numbers:
8 % 2.5   // equals 0.5

The nil coalescing operator (a ?? b) unwraps an optional a if it contains a value, or returns a default value b if a is nil. The expression a is
always of an optional type. The expression b must match the type that is stored inside a.
The nil coalescing operator is shorthand for the code below:
a != nil ? a! : b

The closed range operator (a...b) defines a range that runs from a to b, and includes the values a and b. The value of a must not be greater than b.
for index in 1...5 {
    println("\(index) times 5 is \(index * 5)")
}
The half-open range operator (a..<b) defines a range that runs from a to b, but does not include b.
let names = ["Anna", "Alex", "Brian", "Jack"]
let count = names.count
for i in 0..<count {
    println("Person \(i + 1) is called \(names[i])")
}

5. Strings and Characters
var emptyString = ""               // empty string literal
var anotherEmptyString = String()  // initializer syntax
// these two strings are both empty, and are equivalent to each other

Swift’s String type is a value type. If you create a new String value, that String value is copied when it is passed to a function or method,
or when it is assigned to a constant or variable. In each case, a new copy of the existing String value is created, and the new copy is passed
or assigned, not the original version.
wift’s String and Character types are fully Unicode-compliant

.isEmpty
.hasPrefix
.hasSuffix

6. Collection Types
If you create an array or a dictionary and assign it to a variable, the collection that is created will be mutable. This means
that you can change (or mutate) the collection after it is created by adding, removing, or changing items in the collection.
Conversely, if you assign an array or a dictionary to a constant, that array or dictionary is immutable, and its size and contents cannot be changed.
It is good practice to create immutable collections in all cases where the collection does not need to change.

The type of a Swift array is written in full as Array<SomeType>, where SomeType is the type that the array is allowed to store. You can also write
the type of an array in shorthand form as [SomeType].
var shoppingList: [String] = ["Eggs", "Milk"]
shoppingList.append("Flour")
shoppingList += ["Baking Powder"]
shoppingList += ["Chocolate Spread", "Cheese", "Butter"]
shoppingList[4...6] = ["Bananas", "Apples"]
shoppingList.insert("Maple Syrup", atIndex: 0)
let mapleSyrup = shoppingList.removeAtIndex(0)
let apples = shoppingList.removeLast()
for item in shoppingList {
    println(item)
}
for (index, value) in enumerate(shoppingList) {
    println("Item \(index + 1): \(value)")
}

var someInts = [Int]()
println("someInts is of type [Int] with \(someInts.count) items.")
// prints "someInts is of type [Int] with 0 items."
var threeDoubles = [Double](count: 3, repeatedValue: 0.0)

Unlike items in an array, items in a dictionary do not have a specified order.
The type of a Swift dictionary is written in full as Dictionary<Key, Value> and shorthand form as [Key: Value]
var airports: [String: String] = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
if let oldValue = airports.updateValue("Dublin Airport", forKey: "DUB") {
    println("The old value for DUB was \(oldValue).")
}
remove a key-value pair from a dictionary with the removeValueForKey method.
if let removedValue = airports.removeValueForKey("DUB") {
    println("The removed airport's name is \(removedValue).")
} else {
    println("The airports dictionary does not contain a value for DUB.")
}
// prints "The removed airport's name is Dublin Airport."

for (airportCode, airportName) in airports {
    println("\(airportCode): \(airportName)")
}

for airportCode in airports.keys {
    println("Airport code: \(airportCode)")
}

for airportName in airports.values {
    println("Airport name: \(airportName)")
}

let airportCodes = [String](airports.keys)
// airportCodes is ["YYZ", "LHR"]

7. Functions
func sayHello(personName: String) -> String {
    let greeting = "Hello, " + personName + "!"
    return greeting
}
Functions Without Return Values:
func sayGoodbye(personName: String) {
    println("Goodbye, \(personName)!")
}
sayGoodbye("Dave")
// prints "Goodbye, Dave!"

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.

func swapTwoInts(inout a: Int, inout b: Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}
var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)

func addTwoInts(a: Int, b: Int) -> Int {
    return a + b
}
var mathFunction: (Int, Int) -> Int = addTwoInts
You can now call the assigned function with the name mathFunction:
println("Result: \(mathFunction(2, 3))")

func printMathResult(mathFunction: (Int, Int) -> Int, a: Int, b: Int) {
    println("Result: \(mathFunction(a, b))")
}
printMathResult(addTwoInts, 3, 5)

TODO Closures

No comments:

Post a Comment