Playground

The Xcode platform has a built-in playground mode, that allows you to evaluate the code line by line. I use this tool during learning. If you want to try Swift on Linux, you need to install it first.

Code playground with example Swift code
Xcode playground with example Swift code.

Variables and Constants

Variables

Variables are created using the var keyword. One-line string must be enclosed in double-quotes.

var str = "Hello, Swift"
str = "Goodbye!"

Multi-line strings

To create a multi-line string, use three double-quotes signs and new line, like this:

var joke = """
Why do cows never have any money?
Because the farmers milk them dry!
"""

If you want to keep string multi-line, but display it as a one-line, you need to escape the new lines.

var message = """
This is a very long message \
and I found it quite useful \
to split lines in the code \
but display them as one line.
"""

Types of variables

There are other simple types of variables: Integer, Double, Boolean.

var name = "John Snow" // String
var age = 38           // Integer
var height = 1.78      // Double
var canFight = true    // Boolean

Swift is a type-safe language. Every variable must be one of the specific types. If you try to assign an int to the name variable, the compiler produces the error.

var age = 38
age = "40" // error: cannot assign value of type'String' to type'Int'

Swift can inference the type of variable from value. If you don’t declare value or you want to be explicit, you can add the type after the variable’s name.

var name: String = "John Snow"
var age: Int = 38
var height: Double = 1.78
var canFight: Bool = true

Both Integer and Boolean have short names: Int and Bool.

Thousand separator

If you have a very large integer, you can use an underscore as a thousand separator to make the value more readable. It doesn’t affect the value.

var population = 8_000_000

Constants

You can create a constant using the let keyword. You can use it the same way as the variable with one exception – you can’t change the value after first initialization.

let name: String = "John Snow"
let age: Int = 38
let height: Double = 1.78
let canFight: Bool = true

height = 1.79 // note: change 'let' to 'var' to make it mutable

However, you can defer the initialization. It works like a final modifier in Java.

let height: Double
height = 1.78 // it's OK
height = 1.79 // note: change 'let' to 'var' to make it mutable

Constants are a preferable way to hold values. Even Xcode suggests using let instead of var if you don’t change the value.

Summary

  • Swift doesn’t need to have a semi-colon at the end of the line, but it’s not an error.
  • You can omit the type of variable if you set its value.
  • For very long integers, you can use an underscore as a thousand separator.
  • Constants are a preferable way to hold values.

Data structures

Arrays

To create an array, write comma-separated values in brackets. The type must be also placed in brackets.

let names: [String] = ["John", "Jenny", "Jack"]

If you create an array with at least one element, you can omit the type. Swift will infer it.

let names = ["John", "Josh"]

These constructions produce errors:

let emptyArray = [] // error: empty collection literal requires an explicit type

let anyArray = ["James", 0.4] // error: heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional

Swift allows creating arrays of elements with different types, however, you have to add explicit type annotation: [Any].

   let anyArray: [Any] = ["James", 0.4] 

Arrays are collections of values in a specific order. They may contain duplicates.

You can access the value from an array by its numerical index, counted from 0. If you request the non-existing key, Swift will interrupt the execution.

let group: [String] = ["Jimmy", "Jane", "Jessy"]
group[0] // Jimmy
group[2] // Jessy
group[3] // Fatal error: Index out of range

If you want to create an empty array, you can write something like this:

var usedNamesA = [String]()

Above construction it’s a shorthand for:

var userNamesB = Array<String>() // or
var userNamesC: [String] = []

Dictionaries

Dictionary is an associative array that contains both keys and corresponding values in specific types.

let attendees: [String, Bool] = [
    "Max": true,
    "Bob": false,
    "John": true
]

You can also omit the types if you assign elements to the dictionary.

let attendees = [
    "Max": true,
    "Bob": false,
    "John": true
]

Keys in the dictionary are unique. Swift will produce the error if you initialize the dictionary with duplicated keys.

let attendees = [
    "Max": true,
    "Bob": false,
    "John": true,
    "Max": false // Fatal error: Dictionary literal contains duplicate keys
]

Like in the array, you can retrieve the value from the dictionary using its key. If you request the key that doesn’t exist in the dictionary, you’ll get a nil value.

attendees["Max"]   // true
attendees["Bob"]   // false
attendees["Jenny"] // nil

Sometimes it’s useful to get a different value instead of nil if the key does not exist. In this case, you can set default value after the key’s name. The value has to be in the same type as the rest values in the dictionary, unless it’s declared as Any.

attendees["Jenny"] // nil
attendees["Jenny", default: false] // false
attendees["Jenny", default: "Nope"] // error: cannot subscript a value of type '[String : Bool]' with an argument of type '(String, default: String)'

If you want to define an empty dictionary, you have to specify the type of keys and values.

var attendeesA = [String: Bool]()

Above construction it’s a shorthand for:

var attendeesB: [String: Bool] = [:] // or
var attendeesC = Dictionary<String, String>()

Tuples

Tuples are containers for very specific data. They are fixed – once the tuple is defined, you can’t add or remove data from it. You can change the data if the tuple is mutable.

let person = (name: "John", age: 20, canSign: false)

You can access the data using keys or numerical indexes.

person.0 // John
person.name // John
person.1 // 20
person.age // 20

Sets

Sets, like other data structures, is a container for values of a specific type. However, values in sets are unique and without explicit order. Even if you put duplicated value into the set, it will appear only once.

let colors = Set(["red", "green", "blue", "blue", "red"]) // {"green", "red", "blue"}

To define empty set, you need to use this construction:

var usedColors = Set<String>()

Enum

Enum allows you to create a group of related values.

enum Result {
    case failure
    case success
}

Now, we can use it as a value:

let status = Result.failure
let response = (status: status, message: "Invalid username or password.")

Attach contextual information to enum

If you need to attach more context to enum, you can define the case with parameters.

enum AlertType {
    case success(stick: Bool, title: String)
    case error(fullscreen: Bool)
}

let successMessageType = AlertType.success(stick: true, title: "Yeaa!")
let fatalErrorMessageType = AlertType.error(fullscreen: true)

Create enum from the raw value

Sometimes you need to create enum from the raw value, e.g. the value comes from database or API. You can define an enum with Integer values and then, pass the rawValue parameter to the constructor.

enum Difficulty: Int {
    case easy
    case medium
    case hard
    case cheater
}

let selectedDifficulty = Difficulty(rawValue: 3) // Difficulty.cheater

Indexes are counted from 0. If you want to change them, set the value of one case. Swift will do the rest.

enum Difficulty: Int {
    case easy
    case medium = 2
    case hard
    case cheater
}

let selectedDifficulty = Difficulty(rawValue: 3) // Difficulty.hard

Basic operations

Arithmetic operators

Most operators work in the same way as in other languages.

let numberA = 5
let numberB = 3

let total = numberA + numberB // 8
let difference = numberA - numberB // 2
let product = numberA * numberB // 15
let divided = numberA / numberB // 1
let remainder = numberA % numberB // 2

var score = 50
score -= 20 // subtract 20 from score
score += 5  // add 5 to score
score *= 2  // multiply score by 2
score /= 2  // divide score by 2

numberA == numberB // false
numberA != numberB // true
numberA > numberB  // true
numberA <= numberB // false

Swift compares strings through alphabetical order.

"Marry" >= "Anna" // true
"Josh" < "James"  // false

String and array concatenation

Depending on the context, the + operator has a different meaning. It’s called operator overloading.

// String concatenation
var famousQuote = "Lorem ipsum dolor sit "
famousQuote += "amet"

// Array concatenation
var letters = ["A", "B", "C"]
letters += ["D", "E", "F"] // ["A", "B", "C", "D", "E", "F"]

String interpolation

You can put values in the string using \(...).

let pi = 3.141
let message = "The PI number is close to \(pi)"
let importantMessage = "Breaking News: \(message)!"

Summary

  • Array may contain duplicated values.
  • Dictionary contains keys and values and may return default value if the requested key doesn’t exist.
  • Tuple carries specific, often related data.
  • Set contains unique values and doesn’t guarantee the order of elements.
  • Enum is a group of related values and may contain additional information.
  • Strings are compared through the alphabetical order.
  • The operator + is overloaded and concatenates string and arrays.

Additional Resources