What the difference is
Swift treats text and numbers as different kinds of values. The quotes decide which kind you wrote: "15" is a String, a piece of text made of the characters 1 and 5, and 15 is an Int, a whole number you can calculate with.
let a = "15"
let b = 15
print(type(of: a), type(of: b))
String Int
Printed with print, the two look the same, but they behave differently. Numbers can be added, subtracted and compared by size. Strings can be joined together, measured and searched. Each kind of value supports its own operations.
Why Swift cares so much
Swift is statically typed: every constant and variable has one type, fixed when the program is compiled. The compiler checks every use of a value against its type, so a mix-up is reported before the program runs at all. Swift also never converts between the two types for you. Adding a string and a number is an error, not a guess:
let a = "15"
let b = 15
print(a + b)
error: binary operator '+' cannot be applied to operands of type 'String' and 'Int'
Two strings with + are joined, so "15" + "1" gives "151". Two integers are added, so 15 + 1 gives 16. Operators such as * and - work only on numbers, and "15" * "5" does not compile either.
Choosing a type for your data
A useful question is whether you will ever calculate with the value. An age, a price or a count takes part in arithmetic, so it is a number. A phone number, a postal code or an ID is an identifier. You never add two phone numbers, and leading zeros matter, so these belong in strings. Stored as an Int, the postal code "01234" would lose its first digit: Int("01234") is 1234.
The exercise
The starter code declares both constants with the wrong kind of value:
let age: Int = "29"
let phone: String = 2025550153
The part after the colon, : Int or : String, is a type annotation. It states what the constant must hold, and the value has to agree. The compiler reports one error for each line:
error: cannot convert value of type 'String' to specified type 'Int'
error: cannot convert value of type 'Int' to specified type 'String'
The annotations are right, so you change the values. Take the quotes off 29, because an age is a quantity. Put quotes around 2025550153, because a phone number is an identifier. The line starts with let, so each name is a constant that cannot be reassigned later.
The solution in Swift
let age: Int = 29
let phone: String = "2025550153"
Some details worth remembering:
- The annotation is optional. Swift infers the type from the value, so
let age = 29is anIntandlet phone = "2025550153"is aString. Writing the type out makes the intent visible, and it turns a wrong value into an error at that line. - Quotes are part of the syntax. They are not part of the string's contents.
"29"holds two characters, 2 and 9. - Converting is explicit. To get a number out of text, ask for it:
Int("15")produces an optional,Optional(15), because the text might not be a number. Going the other way,String(15)gives"15". Later lessons cover both.
Common mistakes
- Quoting a number you calculate with.
let price = "9"compiles, but you cannot multiply it until you convert it. - Expecting
+to mix types."Age: " + 29is an error. Convert withString(29)or use interpolation,"Age: \(29)". - Treating identifiers as numbers. Phone numbers, codes and anything with leading zeros are better as strings.
Key takeaways
- Quotes make a
String; no quotes make a number. - A declared type and the value must agree, or the code does not compile.
- Use numbers for values you calculate with and strings for text and identifiers.
