Swift Programming For Complete Beginners Part 6:

String Interpolation & Type Conversion

Posted 9/23/2018.

You can find Part 5 here.

In this series we've done a lot of printing to the console. We've printed strings and constants and variables of other types. But it's often useful to be able to insert constants or variables directly into strings, especially when those constants or variables are values of other types. For example, when you want to say "Hello, [name]!" or "The bank account ending in [lastFourDigits] has a balance of [accountBalance]". In the bank account example, lastFourDigits could be represented as an Int and accountBalance could be a Double.

We have also seen how strict Swift is about types (in Part 3). For example, even though integers and doubles are both numbers, it doesn't always make sense to add them. If you have an integer constant numberOfPeople and a double constant pi, Swift will prevent you from adding them, which makes sense because you can't have a fractional number of people. Or can you? What if you wanted to represent the average number of people who went to a restaurant over the past week? You would start with integer values for the raw data of number of patrons per day, but you would need a double to represent the average.

String Interpolation and Type Conversion solve these problems. In this tutorial we'll see examples of how to use each.

String Interpolation

In Part 4, we wrote the following function:

func sayHelloToPerson(withName name: String) {
    print("Hello, " + name + "!")
}

Here we're building a string to print to the console that uses a function parameter. It works because the parameter of the function, name, is also a string. This is called String Concatenation and it is a perfectly acceptable way to build strings. However, stylistically some programmers prefer to keep the three components of this string together. We can do that with string interpolation.

Create a new Xcode project called "StringInterpolationTypeConversion" and add the following to main.swift:

func sayHelloToPerson(withName name: String) {
    print("Hello, \(name)!")
}

Now the whole string is a single unit. To interpolate the value of name into the string, we use a backslash followed by the value in parentheses.

OK, so we can achieve the same thing using either string concatenation or interpolation. But what if we try the following?

let lastFourDigits = 1234
let accountBalance = 500.26
let message = "The bank account ending in " + lastFourDigits " has a balance of $" + accountBalance

Swift will give you errors because you can't add strings, an integer, and a double together. Let's rewrite this using string interpolation:

let lastFourDigits = 1234
let accountBalance = 500.26
let message = "The bank account ending in \(lastFourDigits) has a balance of $\(accountBalance)."
print(message)

By using string interpolation we are letting Swift know that we want to represent lastFourDigits and accountBalance as string values for use in the larger string message. In this case Swift will do the type conversion for us.

Type Conversion

String interpolation is a special case, but there are other situations where we need to convert one type to another. One example, as we saw above, is when we need to compute the average of an integer value.

As another example, let's say we wanted to buy shares of stock. In most cases, we can't buy partial shares of stock. We have a set amount of money we can invest, and we want to write a function that tells us how many shares of stock we can buy.

Let's try the following:

let priceOfApple = 217.84
let moneyToInvest = 1500.00
func numberOfSharesToBuy(withAvailableFunds availableFunds: Double, stockPrice: Double) -> Int {
    return availableFunds / stockPrice
}

Swift gives us an error, Cannot convert return expression of type 'Double' to return type 'Int'. We can only buy whole shares, so we need to return an Int from this function. However, we are dividing two doubles, so we need to tell Swift that we want to convert the result to an integer.

In this case, Swift has a built-in way to convert doubles to integers. All we need to do is write Int followed by the value we want to convert in parentheses. Replace the above code with the following:

let priceOfApple = 217.84
let moneyToInvest = 1500.00
func numberOfSharesToBuy(withAvailableFunds availableFunds: Double, stockPrice: Double) -> Int {
    return Int(availableFunds / stockPrice)
}
let shares = numberOfSharesToBuy(withAvailableFunds: moneyToInvest, stockPrice: priceOfApple)
print(shares)

The console with print "6", which is the correct number of shares of Apple you could buy with $1,500 at that price. However, if you do the math you'll get "6.89". In this case we want to round down, but it's important to know that Swift will do that when converting a double to an integer.

Let's go back to the restaurant example. If we had 1,250 people go to our restaurant over the past week, we might compute the average like this:

let totalPatrons = 1250
let numberOfDays = 7
print(Double(totalPatrons/numberOfDays))

The console will print "178.0", which is wrong! What's happening here? In our example, Swift will infer totalPatrons and numberOfDays to be integers. We are then dividing two integers, which Swift will represent as another integer, "178". Finally, we are converting that integer to a double to get "178.0".

What we need to do instead is to convert totalPatrons and numberOfDays to double values before dividing them. Let's rewrite the calculation as follows:

let totalPatrons = 1250
let numberOfDays = 7
print(Double(totalPatrons) / Double(numberOfDays))

Now we get "178.57". Much better!

Review Questions

You should now be able to answer these questions: