Download as pdf or txt
Download as pdf or txt
You are on page 1of 9

6COSC004W/7SENG Native Programming Tutorial – Week 2 version 1.

0 – Author: Philip Trwoga 2020

6COSC004W/7SENG Swift Programming Exercises – Week 2

Review of type safety and optionals tutorial

Type Safety and Type Inference

Swift is a type-safe language. A type safe language encourages you to be clear about the types
of values your code can work with. If part of your code requires a String, you cannot pass it
an Int by mistake.
Because Swift is type safe, it performs type checks when compiling your code and flags any
mismatched types as errors. This enables you to catch and fix errors as early as possible in the
development process.
Type-checking helps you avoid errors when you are working with different types of values.
However, this doesn’t mean that you have to specify the type of every constant and variable
that you declare. If you don’t specify the type of value you need, Swift uses type inference to
work out the appropriate type. Type inference enables a compiler to deduce the type of a
particular expression automatically when it compiles your code, simply by examining the
values you provide.
Because of type inference, Swift requires far fewer type declarations than languages such as
C or Objective-C.
Type inference is particularly useful when you declare a constant or variable with an initial
value. This is often done by assigning a literal value (or literal) to the constant or variable at
the point that you declare it. (A literal value is a value that appears directly in your source
code, such as 42 and 3.14159 in the examples below.)
For example, if you assign a literal value of 42 to a new constant without saying what type it
is, Swift infers that you want the constant to be an Int, because you have initialized it with a
number that looks like an integer:

Likewise, if you don’t specify a type for a floating-point literal, Swift infers that you want to
create a Double:

1. let pi = 3.14159
2. // pi is inferred to be of type Double

Swift always chooses Double (rather than Float) when inferring the type of floating-point
numbers.
If you combine integer and floating-point literals in an expression, a type of Double will be
inferred from the context:
1. let pi = 3 + 0.14159
2. // pi is also inferred to be of type Double
6COSC004W/7SENG Native Programming Tutorial – Week 2 version 1.0 – Author: Philip Trwoga 2020
6COSC004W/7SENG Native Programming Tutorial – Week 2 version 1.0 – Author: Philip Trwoga 2020

Optionals

You use optionals in situations where a value may be absent. An optional represents two
possibilities: Either there is a value, and you can unwrap the optional to access that value, or
there is not a value.

To undertake this tutorial, first create a new iOS playground in XCode and then try the
following code. Note that everything that is wrapped in a /**some notes */ are just guidance
notes.

import UIKit

//Optionals Playground

/**

This tutorial will focus on optionals, what they are and when to use them
An optional either has a value or is nil
They are used when you cannot necessarliy specify a default value to a type or you
want a have the ability for a var to return nil
So, you use optionals in situations where a value may be absent. An optional
represents two possibilities: Either there is a value, and you can unwrap the optional
to access that value, or there is not a value.
*/

//usual declaration of a type


var a = 2 //inferred to be an int
/**Below is an optional declaration - not the ? mark.
*/
var aOpt:Int? //see what type this is by left-click + option key

//let's now try to print this


print(aOpt)
//what was the output and message - can you explain the message? If not just make
a note of it
6COSC004W/7SENG Native Programming Tutorial – Week 2 version 1.0 – Author: Philip Trwoga 2020

//let’s try to do some maths with this (uncomment to try)

//let c = a * aOpt

//you will note that we need to unwrap this so let try this - note down what happens
(uncomment to try)

//let c2 = a * aOpt!

//the above went wrong because aOpt is returning nil

//let's assign a value to aOpt and try again

aOpt = 5

//try the line below first by uncommenting then commenting again when you are done

//let c2 = a * aOpt

// you will see we need to unwrap the optional to see what it is


// we do this using the ! after the name as below

let c2 = a * aOpt!

//this now works ok

//lets try this – uncomment the second line


6COSC004W/7SENG Native Programming Tutorial – Week 2 version 1.0 – Author: Philip Trwoga 2020

aOpt = nil

//let c3 = a * aOpt!

/**
Now we are back to the same problem of the nil return - note this would crash an
application
You can therefore set an optional variable to a valueless state by assigning it the
special value nil
*/

/**
So how do we do this safely? - maybe we are never sure if the optional as assigned
at any particular time, as this might be down to the user or maybe via some external
service
*/

//check for nil

if aOpt != nil
{
let c4 = a * aOpt!
}
else
{
print("value not assigned")
}

/**
So, once you are 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.
6COSC004W/7SENG Native Programming Tutorial – Week 2 version 1.0 – Author: Philip Trwoga 2020

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 you define an optional variable without providing a default value, the variable is
automatically set to nil for you
*/

var name: String?


//in the above, name is automatically set to nil

/**
Optional Binding
You use optional binding to find out whether an optional contains a value, and if so, to
make that value available as a temporary constant or variable. Optional binding can
be used with if and while statements to check for a value inside an optional, and to
extract that value into a constant or variable, as part of a single action
*/

aOpt = 7 //also try with this line commented out also

if let actualNumber = aOpt {


print("The number \(aOpt) has an integer value of \(actualNumber)")
} else {
print("The number \(aOpt) has not been assigned a number")
}
// Prints "The string "123" has an integer value of 123"

/**
This code can be read as:
“If the optional Int returned by aOpt contains a value, set a new constant called
actualNumber to the value contained in the optional.”
You can use both constants and variables with optional binding - in the above example
you would use var if you wished to further manipulate 'actualNumber'
6COSC004W/7SENG Native Programming Tutorial – Week 2 version 1.0 – Author: Philip Trwoga 2020

*/

/**
You can include as many optional bindings and Boolean conditions in a single if
statement as you need to, separated by commas. If any of the values in the optional
bindings are nil or any Boolean condition evaluates to false, the whole if statement’s
condition is considered to be false. The following if statements are equivalent:
*/

aOpt = 4

var aOpt2:Int? = 42
//var aOpt2:Int? //try this too

//try the above with and without a value to see what happens

if let firstNumber = aOpt, let secondNumber = aOpt2, firstNumber < secondNumber


&& secondNumber < 100 {
print("\(firstNumber) < \(secondNumber) < 100")
}
// Prints "4 < 42 < 100"

/**

NOTE:
Constants and variables created with optional binding in an if statement are available
only within the body of the if statement.
*/

/**
Implicitly Unwrapped Optionals
As described above, optionals indicate that a constant or variable is allowed to have
“no value”. Optionals can be checked with an if statement to see if a value exists, and
6COSC004W/7SENG Native Programming Tutorial – Week 2 version 1.0 – Author: Philip Trwoga 2020

can be conditionally unwrapped with optional binding to access the optional’s value if
it does exist.

Sometimes it is clear from a program’s structure that an optional will always have a
value, after that value is first set. In these cases, it’s useful to remove the need to
check and unwrap the optional’s value every time it’s accessed, because it can be
safely assumed to have a value all of the time.

Note: that outlets from a storyboard are of this type as they have a definite value since
they exist on the storyboard view

These kinds of optionals are defined as implicitly unwrapped optionals. You write an
implicitly unwrapped optional by placing an exclamation mark (String!) rather than a
question mark (String?) after the type that you want to make optional.

Implicitly unwrapped optionals are useful when an optional’s value is confirmed to


exist immediately after the optional is first defined and can definitely be assumed to
exist at every point thereafter.

An implicitly unwrapped optional is a normal optional behind the scenes but can also
be used like a non-optional value, without the need to unwrap the optional value each
time it’s accessed.

*/

let possibleString: String? = "An optional string."


let forcedString: String = possibleString! // requires an exclamation mark

let assumedString: String! = "An implicitly unwrapped optional string."


let implicitString: String = assumedString // no need for an exclamation mark

//CHALLENGES

/**
Which of the following are valid statements?
Do not try these on the command line, see if you be the compiler and work out which
statement is valid:
6COSC004W/7SENG Native Programming Tutorial – Week 2 version 1.0 – Author: Philip Trwoga 2020

var name: String? = "Phil"


var age: Int = nil
let distance: Float = 26.7
var middleName: String? = nil

/**
Practise with optionals in a function

First, create a function that returns the number of times an integer can be divided by
another integer without a remainder. The function should return nil if the division
doesn’t produce a whole number. Name the function divideIfWhole.

Then, write code that tries to unwrap the optional result of the function. There should
be two cases: upon success, print "It divides \(answer) times", and upon failure, print
"Not divisible".

Finally, test your function:

Divide 10 by 2. This should print "It divides 5 times."


Divide 10 by 3. This should print "Not divisible "

Hint 1: Use the following as the start of the function signature:


*/
func divideIfWhole(value: Int, by divisor: Int){
return...
}
You’ll need to add the return type, which will be an optional
*/
/**
Hint 2: You can use the modulo operator (%) to determine if a value is divisible by
another; recall that this operation returns the remainder from the division of two
numbers. For example, 10 % 2 = 0 means that 10 is divisible by 2 with no remainder,
whereas 10 % 3 = 1 means that 10 is divisible by 3 with a remainder of 1
*/

End of tutorial

You might also like