Let's Learn a Little Swift: Basic Data Types

Now that we've learned about variables and constants in Let's Learn a Little Swift, we're going to expand on a topic we briefly touched on in that post: data types.

What are data types?

In programming, a data type specifies the type of data that can be stored inside of a variable or constant. We‘ve already touched on two, Strings and Integers. For a refresher, a string holds textual data and the text must be contained in double quotes (").

// A constant named exampleString which holds the String value of "This is an example string"
let exampleString: String = "This is an example string"

An Integer, or Int in Swift, holds whole numbers. These numbers can be positive or negative, but they must be whole. Integers cannot be fractional values.

// Valid Int
let validInteger: Int = 21
let anotherValidInteger: Int = -21

//Invalid Int
let invalidInteger: Int = 2.1

Another thing to note about integers are that they have minimum and maximum values. I don't want to confuse you with the differences between Int32 and Int64 here, but feel free to click the link to learn more about the different sizes.

Now let's look at some new data types.

Character

A character represents a single-character String. We create a character-type variable by using the Character keyword.

// Valid character
var validCharacter: Character = "A"

// Invalid character
var invalidCharacter: Character = "ABC"

You may have noticed something important here. Characters and Strings are both created by wrapping text in double quotes. This highlights the importance of explicitly typing your variables. Swift can usually infer what type of value your variable contains without explicitly stating it, but Strings and Characters can be difficult to differentiate. Let's look at an example to illustrate this potential issue. Feel free to try this yourself in Swift Playgrounds.

// Character
var letterGrade = "A"

// Built-in function that returns the type of the variable we provide as a parameter
print(type(of: letterGrade))
Running the code outputs a value of "String".

As we can see, even though we only entered a single character as our value for letterGrade , Swift interpreted this as a String type. Now, let's try to explicitly tell Swift the type of value we intend to store.

var letterGrade: Character = "A"

print(type(of: letterGrade))
Running the code outputs a value of "Character".

To ensure we understand the difference between String and Character types, let's try some invalid code. Feel free to experiment with this in Swift Playgrounds, creating strings and characters to hammer home the difference between the two.

// Invalid Character type
var letterGrade: Character = "A+"
Typing out that code immediately produces an error.

Explicitly typing values can be a great way to ensure you don't make mistakes in the future. If you rely on a variable holding a single character like "Y" or "N" for example, you don't want to be able to accidentally make a typo and create a value of "Yu" while you're up coding at 2 am. Explicitly setting a type to Character allows the Swift compiler to alert you that you're making a mistake.

Float and Double

Remember how we said Int values can only hold whole numbers? Well we can create fractional numbers, or decimals, by using Double or Float values.

Float values are 32-bit numbers that can store value with up to 6 decimal places or 1.2 x 10-38 to 3.4 x 1038 if you're a math person (I am not). Since float values are smaller numbers, they may have to be rounded and cannot be guaranteed to be completely accurate. More on that later.

// Sufficient for numbers with fewer decimal places
var temperature: Float = 96.8

Double values are 64-bit numbers and support data up to 15 decimal places or 2.3 x 10-308 to 1.7 x 10308 again for my math people. Since these numbers are larger, they have a better chance of accuracy, but still can run into issues there.

// Sufficient for numbers with more decimal places
var pi: Double = 3.14159

As a beginner, and because modern-day devices have enough memory to support it, stick with Double values for decimal numbers unless working with a specific API that requires otherwise.

Why does accuracy matter?

What situation would you want pinpoint accuracy when it comes to decimal numbers? Money! Let's look at an example:

var subtotal: Double = 29.99
var salesTax: Double = 1.95

var totalPrice = subtotal + salesTax

print(totalPrice)
Running this code outputs 31.939999999999998

If you are programming a cash register, do you want to tell your customer they owe you $31.939999999999998? This may not seem like a big deal at first, but this small inaccuracy can add up when you're doing several transactions in a day. If you're anything like me, you don't play about your coins! So now that we see the problem, how can we accurately handle financial values?

Decimal

Swift's Foundation framework contains a value called Decimal that is better suited to handle financial calculations. Let's see the difference when doing the same operation as above. To use decimal types, we need to import the Foundation framework at the top of our project.

import Foundation

var subtotal: Decimal = 29.99
var salesTax: Decimal = 1.95

var totalPrice = subtotal + salesTax

print(totalPrice)
Using the Decimal type, the same operation now correctly outputs 31.94

That looks much better, and will guarantee accuracy when handling base-10 calculations.

Boolean

The last data type we will cover today is the Boolean or Bool in Swift. Boolean values can either be true or false and are great for situations where all you need to know is yes or no. A real-life example would be something like a light switch. The switch is either on (true) or off (false). In code, we often need to make decisions based on simple yes/no questions. Let's work through an example.

let isBennett: Bool = true

if isBennett {
    print("Not in it.")
} else {
    print("In it.")
}
Running that code prints "Not in it."

What we did here is use an if...else statement to evaluate if the value contained inside of isBennett is true. If the value is true, it will run the code inside of the first set of curly braces, or the "if" block. If the value is false, it will run the code inside of the "else" block.

You can read this as "If true, print 'Not in it.'. Otherwise, print 'In it.'" where the condition is the value of isBennett. The value we print depends on whether the boolean is equal to true or false.

Booleans are very powerful in programming and can be used to conditionally run code within your applications.

Putting it all together

Let's try to put this all together in a simple application that outputs a letter grade based on a percentage. Feel free to copy/paste this code as it is long, but the value comes from inputting different values and playing with it yourself.

let studentName: String = "Penny Proud"
let percentage: Double = 92.5

// When we don't set a value initially, we can assign a value later in code.
let finalLetterGrade: Character
let passed: Bool

// This sets passed to true if the percentage is greater than or equal to 60
if percentage >= 60 {
    passed = true
} else {
    passed = false
}

// We can then set the finalLetterGrade based on the percentage

if percentage >= 90 {
    finalLetterGrade = "A"
} else if percentage >= 80 {
    finalLetterGrade = "B"
} else if percentage >= 70 {
    finalLetterGrade = "C"
} else if percentage >= 60 {
    finalLetterGrade = "D"
} else {
    finalLetterGrade = "F"
}

// Finally, we can print a string telling us whether our student has passed or failed.

if passed {
    print("\(studentName) has passed Basic Data Types with a final grade of \(finalLetterGrade). Congratulations!")
} else {
    print("\(studentName) has failed Basic Data Types.")
}

Let's go through some of the code here so that we're not too lost.

The values of studentName and percentage are assigned default values of "Penny Proud" and 92.5 respectively. Then we create two constants that are not given default values. This is because their value will be based on a calculation that we make later in our code. Would it make sense to hardcode a value to finalLetterGrade? Not in this example because its value is dependent on the value of percentage and we want our program to dynamically determine the letter grade with our if...else statement. Same with the value for passed.

A brief note on if...else statements

If you clicked the link earlier to learn more about if...else statements, you would have seen that you can also use if...else if...else statements to evaluate multiple conditions. The order in which we do this is also very important. For example try changing the order in which the conditions are evaluated. Replace the current statement with the one below:

if percentage >= 60 {
    finalLetterGrade = "D"
} else if percentage >= 70 {
    finalLetterGrade = "C"
} else if percentage >= 80 {
    finalLetterGrade = "B"
} else if percentage >= 90 {
    finalLetterGrade = "A"
} else {
    finalLetterGrade = "F"
}

If we run the code with the same percentage value of 92.5, you'll see an output that says "Penny Proud has passed Basic Data Types with a final grade of D. Congratulations!" This is because the statement will stop evaluating as soon as the condition evaluates to "true". So since 92.5 is greater than or equal to 60, this is true and gives the student a "D".

If you insist on evaluating backwards from F to A, you would have to change the conditions as follows:

if percentage < 60 {
    finalLetterGrade = "F"
} else if percentage < 70 {
    finalLetterGrade = "D"
} else if percentage < 80 {
    finalLetterGrade = "C"
} else if percentage < 90 {
    finalLetterGrade = "B"
} else {
    finalLetterGrade = "A"
} 

I encourage you to play around with these statements to understand why they have to be made in a specific order to evaluate correctly. Enter different percentages and see how they evaluate based on the conditions you set and their order.

That was a LOT of new information and I understand how easy it is to be confused with these concepts. If you feel stuck, feel free to leave a comment below for clarification.

Subscribe to Danielle Lewis

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe