A struct, or structure, is a custom data type in Swift that allows you to add many properties to it. If you think of a regular string, you can store just one string in the variable, as follows:
var firstName = "Matthew"
What if we wanted to add Matthews height:
var firstName = "Matthew"
var height = 190
This rapidly becomes complicated because we now have two variables to manage and think about. Imagine if we needed to add their last name, and so on, and then have the need to pass this information somewhere else within the program. This is one benefit of using a struct.
We define this struct as follows:
struct Person {
let firstName: String
let lastName: String
let height: Float
}
The struct is defined as Person, and a person has a first name, last name, and height.
We can use this struct as follows:
struct Person {
let firstName: String
let lastName: String
let height: Float
}
let person = Person(firstName: "Matthew", lastName: "Newill", height: 190.5)
print(person) // prints everything about the person.
print("My name is \(person.firstName) \(person.lastName)") // gives us a friendly string including their first and last name.
On line 7 we declare a constant called Person and set it to Person. We provide the required information which is firstName, lastName, and height.
We can now print this person (line 9), or we can access its properties direct with person.firstName and so on.
Constants and Variables
When creating an instance of a struct you can choose to make this a constant with the word “let” or a variable with the word “var”. The above example showed person being declared as a constant.
If you declare the structure as a constant then you can initialise the contents, but you cannot change the contents.
You also have the ability to set individual properties as constants or variables, although if you declare the struct as a constant, none of them will be editable.
struct Person {
let firstName: String
var lastName: String
let height: Float
}
var person = Person(firstName: "Matthew", lastName: "Newill", height: 190.5)
person.lastName = "Johnson"
In the example above, firstName and height are constants, but lastName is a variable. Because person was declared as a variable on line 7, this makes lastName now changeable with that property being a variable.
However, if line 7 declared person as a constant then after initialising person, nothing would be changeable, even if the properties are variables.
Structs Can Have Computed Properties
As well as storing properties in a struct, you can also use computed properties which are properties where you don’t set a value, and yet, one is given to you.
One example of when this could be useful is where a calculation needs to be performed. Let’s look at the example of a person struct that also has weight and height properties.
struct Person {
var firstName: String
var lastName: String
var height: Float // cm
var weight: Float // kg
var bmi: Float {
return weight/((height/100)*(height/100))
}
}
var person = Person(firstName: "John",
lastName: "Smith",
height: 170.5,
weight: 75.2)
print("\(person.firstName), you weigh \(person.weight)Kg and your BMI is \(person.bmi)")
On line 6 we added a computed property for BMI (body mass index). Computed properties need to be declared as variables and not constants. This returns a simple (and standard) calculation which is the weight in KG divided by the height in meters (squared).
When we instantiate person on lines 11 to 14 we do not set the BMI property. Instead, we just ignore it, but as seen on line 16 we can access it through person.bmi.
Structs Can Have Methods
In a similar vein, structs also have methods. These are declared with the func keyword and can be used to do something with the struct. Technically it is OK to declare bmi from the last example as a function. If doing it this way, you would declare the Person stuct as follows:
struct Person {
var firstName: String
var lastName: String
var height: Float // cm
var weight: Float // kg
// var bmi: Float {
// return weight/((height/100)*(height/100))
// }
func bmi() -> Float {
return weight/((height/100)*(height/100))
}
}
...
print("\(person.firstName), you weigh \(person.weight)Kg and your BMI is \(person.bmi())")
The BMI function is declared on line 10. We have a method called BMI that accepts no arguments, returns a float, and then in the implementation, we return a float using the same formula as the calculated property in the section above.
Note that on line 17 we access a function slightly differently than we would a property. We access the person.bmi() method and not person.bmi (the property).
Which to Use on Swift Structs: Computed Properties or Methods
There are no hard and fast rules on which type to use, but some common themes of when to use a computed property or a method include the following:
- If you want to get the information and have no need to send arguments, then a computed property could be the right option.
- If you want to get the information, but need to send argument(s) then a method would be needed.
- Computed properties often return state. If you are fetching a state then use a computed property.
- If you need to mutate data either via an argument or simply just by calling a method with no parameters, such as marking an email as read, then use a function.
- If you need to loop over items and perform something more complex, you would likely use a method.
Structs allow you to make complex data types. These are ideal when you need to pass instances of the object around. Structs are powerful and can be used in many places in your project. We will look at classes next and what the differences are and when to use a class or a struct.
Leave a Reply
You must be logged in to post a comment.