Let's step through the preceding code line by line to understand it:
let phrase: String = "The quick brown fox jumps over the lazy dog"
We designate that we want to assign a constant by using the let keyword, and we give that constant a name--phrase. After the :, we define the type of constant we want to assign; in this case, we want to assign a String (String is how most programming languages refer to text). The = sign indicates that we are assigning a value to the constant we have defined, and The quick brown fox jumps over the lazy dog is a String literal, which means that it's an easy way to construct a string. So, we are assigning the String literal on the right-hand side of the = sign to the constant on the left-hand side of the = sign:
let numberOfFoxes: Int = 1
let numberOfAnimals: Int = 2
Now, we will assign some more constants, but this time they are Int, or integers:
let averageCharactersPerWord: Float = (3+5+5+3+5+4+3+4+3) / 9
Rather than assigning a value directly, we can assign the outcome from a mathematical expression to the constant. This constant is a Float or floating point number; in other words, it can store fractions rather than integers:
print(averageCharactersPerWord)
The print function allows us to see the output from any expression printed to the console or displayed in the playground. The playground has displayed the output of the statement as 3.88889. The actual value of the mathematical expression we performed is 3.88888888... with an infinite number of 8s. However, the print function has rounded this up to just five decimal places. This potential difference between the true value of a floating point number and how it's represented by the Swift language is important to remember when dealing with floats:
phrase = "The quick brown ? jumps over the lazy ?" // Doesn't compile
The playground doesn't produce an output for this line because it is commented out. The /* syntax before the line and the */ syntax after the line denote that this is a comment block, so the Swift compiler should ignore anything typed in this block.
Remove /* and */ (you'll see that // Doesn't compile is still highlighted in green; this is because // denotes that anything after this, on the same line, is also a comment); now try and run the code. The code cannot run because the compiler has detected a problem with this line, so let's look at the line to determine the issue.
On the left-hand side of the = sign, we have phrase, which we declared earlier, and now we are trying to assign a new value to it. We can't do this because we defined phrase as a constant using the let keyword. We should only use let for things we know will not change. If we want to define something that can change, we declare it as a variable using the var keyword:
var anotherPhrase = phrase
Here, we take our constant phrase and assign it to the anotherPhrase variable. This ability to define something as unchanging, or immutable, is an important concept in Swift, and we will revisit in the later chapters:
anotherPhrase = "The quick brown jumps over the lazy "
Since anotherPhrase is a variable, we can assign a new value to it. Strings in Swift are fully Unicode compliant, so we can have some fun and use emojis instead of words:
print(phrase) // "The quick brown fox jumps over the lazy dog"
print(anotherPhrase) // "The quick brown jumps over the lazy "
In the preceding lines, we have done the following:
- Defined a string called phrase
- Defined a string called anotherPhrase as having the same value as phrase
- Changed the value of anotherPhrase
- Printed the value of phrase and anotherPhrase
When we do this, we see that only anotherPhrase prints the new value that was assigned, even though the values of phrase and anotherPhrase were initially the same. Although phrase and anotherPhrase had the same value, they do not have an intrinsic connection; so, when anotherPhrase is assigned a new value, this does not affect phrase.
Strings can be easily combined using the + operator; this gives the expected result:
var phraseInfo = "The phrase" + " has: "
print(phraseInfo) // "The phrase has: "
You will often want to create strings by including values derived from other expressions. We can do this with String interpolation. The values inserted after \( and before ) can be anything that can be represented as a string, including other Strings, Ints, Floats, or expressions:
phraseInfo = phraseInfo + "\(numberOfFoxes) fox and \(numberOfAnimals) animals"
print(phraseInfo) // "The phrase has: 1 fox and 2 animals"
Multiline string literals can be defined using """ at the beginning and end of the string. The contents of the multiline string must be on a separate line from the start and end signifiers; there is no need to escape and use " within the string as you would need to do in a single-line string:
let multilineExplanation = """
Why is the following phrase often used?
"The quick brown fox jumps over the lazy dog"
This phrase contains every letter in the alphabet.
"""
Multiline string literals were introduced with Swift 4 and are not available in Swift 3.
Strings in Swift are collections, which are containers of elements; in this case, a string is a collection of characters. We will cover collections in more depth in a later recipe, but for now, it's enough to know that your collections can tell you how many elements they contain through their count property. We use this to output the number of characters in the phrase:
print("Number of characters in phrase: \(phrase.count)")
The concept of strings acting as collections was introduced with Swift 4. In Swift 3, you could not get a string's character count directly; instead, you could access the character array within the String and get its count property. This means that the preceding print statement would be print("Number of characters in phrase: \(phrase.characters.count)"). In Swift 4, String still has a character array, and therefore code written for Swift 3 will continue to work in Swift 4.
Boolean values represent either true or false. Here, we are assigning the result of the phrase == anotherPhrase equality expression to the phrasesAreEqual constant. The == operator compares the values on the left- and right-hand side of the operator:
let phrasesAreEqual: Bool = phrase == anotherPhrase
print(phrasesAreEqual) // false
As we discussed earlier, although we assigned anotherPhrase the value of phrase initially, we then assigned a new, different value to anotherPhrase; therefore, phrase does not equal anotherPhrase, and the expression assigns the Boolean value of false:
let phraseHas43Characters: Bool = phrase.characters.count == 40 + 3
print(phraseHas43Characters) // true
Each side of the == operator can be any expression that evaluates to match the type of the other side. In this case, the character count of phrase equals 43, so the constant is assigned the value of true.