Swift is a type-safe language
which means the language helps you to be clear about the types of values your code can work with. If part of your code expects a String, type safety prevents you from passing it an Int by mistake. Likewise, type safety prevents you from accidentally passing an optional String to a piece of code that expects a nonoptional String. Type safety helps you catch and fix errors as early as possible in the development process.
Constants and Variables
declare constants with the let
keyword and variables with the var
keyword
1 | let maximumNumberOfLoginAttempts = 10 |
Type Annotations
1 | var welcomeMessage: String |
Naming Constants and Variables
1 | let π = 3.14159 |
Integers
- Integers are either signed (positive, zero, or negative) or unsigned (positive or zero).
- Unless you need to work with a specific size of integer, always use
Int
for integer values in your code - Swift also provides an unsigned integer type, UInt, which has the same size as the current platform’s native word size:
Floating-Point Numbers
Swift provides two signed floating-point number types:
- Double represents a 64-bit floating-point number. Double has a precision of at least 15 decimal digits, whereas the precision of Float can be as little as 6 decimal digits. In situations where either type would be appropriate, Double is preferred
- Float represents a 32-bit floating-point number.
Numeric Literals
All of these integer literals have a decimal value of 17:
1 | let decimalInteger = 17 |
All of these floating-point literals have a decimal value of 12.1875:
1 | let decimalDouble = 12.1875 |
Both integers and floats can be padded with extra zeros and can contain underscores to help with readability
1 | let paddedDouble = 000123.456 |
Numeric Type Conversion
Integer Conversion
An Int8 constant or variable can store numbers between -128 and 127, whereas a UInt8 constant or variable can store numbers between 0 and 255.
1 | let cannotBeNegative: UInt8 = -1 |
SomeType(ofInitialValue)
is the default way to call the initializer of a Swift type and pass in an initial value
1 | let twoThousand: UInt16 = 2_000 |
Integer and Floating-Point Conversion
The rules for combining numeric constants and variables are different from the rules for numeric literals. The literal value 3 can be added directly to the literal value 0.14159, because number literals do not have an explicit type in and of themselves. Their type is inferred only at the point that they are evaluated by the compiler.
1 | let three = 3 |
Type Aliases
Type aliases define an alternative name for an existing type. You define type aliases with the typealias keyword.
1 | typealias AudioSample = UInt16 |
Booleans
Swift provides two Boolean constant values, true and false:
1 | let orangesAreOrange = true |
Tuples
What is tuples
Tuples group multiple values into a single compound value. The values within a tuple can be of any type and do not have to be of the same type as each other.
When to use tuples
- Tuples are particularly useful as the return values of functions
- 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.
Declare tuples
“a tuple of type (Int, String)”.
1 | let http404Error = (404, "Not Found") |
Decompose a tuple
You can decompose a tuple’s contents into separate constants or variables
1 | let (statusCode, statusMessage) = http404Error |
ignore parts of the tuple with an underscore (_) when you decompose the tuple
1 | let (justTheStatusCode, _) = http404Error |
Access a tuple
access the individual element values in a tuple using index numbers starting at zero:
1 | print("The status code is \(http404Error.0)") |
name the individual elements in a tuple when the tuple is defined
1 | let http200Status = (statusCode: 200, description: "OK") |
Optionals
What is optionals
An optional represents two possibilities: Either there is a value, and you can unwrap the optional to access that value, or there isn’t a value at all.
nil
cannot be used with nonoptional constants and variables.
Swift’s nil is not the same as nil in Objective-C. In Objective-C, nil is a pointer to a nonexistent object. In Swift, nil is not a pointer—it is the absence of a value of a certain type.
Optionals of any type can be set to nil, not just object types.
1 | let possibleNumber = "123" |
Default value for optionals
If you define an optional variable without providing a default value, the variable is automatically set to nil for you:
1 | var surveyAnswer: String? |
If Statements and Forced Unwrapping
comparison with the “equal to” operator (==) or the “not equal to” operator (!=).
1 | if convertedNumber != nil { |
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:
Always make sure that an optional contains a non-nil value before using ! to force-unwrap its value.
1 | if convertedNumber != 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.
1 | if let constantName = someOptional { |
“If the optional Int returned by Int(possibleNumber) contains a value, set a new constant called actualNumber to the value contained in the optional.”
1 | if let actualNumber = Int(possibleNumber) { |
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.
1 | if let firstNumber = Int("4"), let secondNumber = Int("42"), firstNumber < secondNumber && secondNumber < 100 { |
Implicitly Unwrapped Optionals
You can think of an implicitly unwrapped optional as giving permission for the optional to be unwrapped automatically whenever it is used. Rather than placing an exclamation mark after the optional’s name each time you use it, you place an exclamation mark after the optional’s type when you declare it.
Do not use an implicitly unwrapped optional when there is a possibility of a variable becoming nil at a later point. Always use a normal optional type if you need to check for a nil value during the lifetime of a variable.
1 | let possibleString: String? = "An optional string." |
You can still treat an implicitly unwrapped optional like a normal optional, to check if it contains a value:
1 | if assumedString != nil { |
You can also use an implicitly unwrapped optional with optional binding, to check and unwrap its value in a single statement:
1 | if let definiteString = assumedString { |
Error Handling
1 | func makeASandwich() throws { |
Assertions
You use an assertion to make sure that an essential condition is satisfied before executing any further code. 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.
1 | let age = -3 |