Skip to main content

Day 08

About 7 minSwiftcrashcoursepaul-hudsonswifthacking-with-swiftxcodeappstore

Day 08 관련


100 Days of Swift - Day 8

Structs, part one

Structs, part one

I know some of you might be keen to charge on with today’s new Swift learning, but hold up: you just finished learning about closures, which are a difficult topic. And you came back for more. Seriously, that deserves a lot of respect.

And I have some good news for you. First, not only will we be covering closures again in a consolidation day next week, but soon enough we’ll also start putting them into practice in real iOS projects. So, even if you aren’t 100% sure of how they work or why they are needed, it will all become clear – stick with it!

Anyway, today’s topic is structs. Structs let us create our own data types out of several small types. For example, you might put three strings and a boolean together and say that represents a user in your app.

These custom types – users, games, documents, and more – form the real core of the software we build. If you get those right then often your code will follow.

As Fred Brooks, the author of the hugely influential book The Mythical Man-Month, once said, “the programmer at wit’s end... can often do best by disentangling themself from their code, rearing back, and contemplating their data. Representation is the essence of programming.”

Today you have seven one-minute videos to watch, and you’ll learn how to create your own types, adding properties, methods, and more. Once you’ve completed each video, there is a short piece of optional extra reading if you’re looking to get some more details, and there’s also a short test to help make sure you’ve understood what was taught.

1. Creating your own structs

1. Creating your own structs
100 Days of Swift - Day 8 - 1. Creating your own structs

1. Creating your own structs

Swift lets you design your own types in two ways, of which the most common are called structures, or just structs. Structs can be given their own variables and constants, and their own functions, then created and used however you want.

Let’s start with a simple example: we’re going to create a Sport struct that stores its name as a string. Variables inside structs are called properties, so this is a struct with one property:

struct Sport {
    var name: String
}

That defines the type, so now we can create and use an instance of it:

var tennis = Sport(name: "Tennis")
print(tennis.name)

We made both name and tennis variable, so we can change them just like regular variables:

tennis.name = "Lawn tennis"

Properties can have default values just like regular variables, and you can usually rely on Swift’s type inference.

1. Creating your own structs - Additional

2. Computed properties

2. Computed properties
100 Days of Swift - Day 8 - 2. Computed properties

2. Computed properties

We just created a Sport struct like this:

struct Sport {
    var name: String
}

That has a name property that stores a String. These are called stored properties, because Swift has a different kind of property called a computed property – a property that runs code to figure out its value.

We’re going to add another stored property to the Sport struct, then a computed property. Here’s how that looks:

struct Sport {
    var name: String
    var isOlympicSport: Bool

    var olympicStatus: String {
        if isOlympicSport {
            return "\(name) is an Olympic sport"
        } else {
            return "\(name) is not an Olympic sport"
        }
    }
}

As you can see, olympicStatus looks like a regular String, but it returns different values depending on the other properties.

We can try it out by creating a new instance of Sport:

let chessBoxing = Sport(name: "Chessboxing", isOlympicSport: false)
print(chessBoxing.olympicStatus)

3. Property observers

3. Property observers
100 Days of Swift - Day 8 - 3. Property observers

3. Property observers

Property observers let you run code before or after any property changes. To demonstrate this, we’ll write a Progress struct that tracks a task and a completion percentage:

struct Progress {
    var task: String
    var amount: Int
}

We can now create an instance of that struct and adjust its progress over time:

var progress = Progress(task: "Loading data", amount: 0)
progress.amount = 30
progress.amount = 80
progress.amount = 100

What we want to happen is for Swift to print a message every time amount changes, and we can use a didSet property observer for that. This will run some code every time amount changes:

struct Progress {
    var task: String
    var amount: Int {
        didSet {
            print("\(task) is now \(amount)% complete")
        }
    }
}

You can also use willSet to take action before a property changes, but that is rarely used.

4. Methods

4. Methods
100 Days of Swift - Day 8 - 4. Methods

4. Methods

Structs can have functions inside them, and those functions can use the properties of the struct as they need to. Functions inside structs are called methods, but they still use the same func keyword.

We can demonstrate this with a City struct. This will have a population property that stores how many people are in the city, plus a collectTaxes() method that returns the population count multiplied by 1000. Because the method belongs to City it can read the current city’s population property.

Here’s the code:

struct City {
    var population: Int

    func collectTaxes() -> Int {
        return population * 1000
    }
}

That method belongs to the struct, so we call it on instances of the struct like this:

let london = City(population: 9_000_000)
london.collectTaxes()

5. Mutating methods

5. Mutating methods
100 Days of Swift - Day 8 - 5. Mutating methods

5. Mutating methods

If a struct has a variable property but the instance of the struct was created as a constant, that property can’t be changed – the struct is constant, so all its properties are also constant regardless of how they were created.

The problem is that when you create the struct Swift has no idea whether you will use it with constants or variables, so by default it takes the safe approach: Swift won’t let you write methods that change properties unless you specifically request it.

When you want to change a property inside a method, you need to mark it using the mutating keyword, like this:

struct Person {
    var name: String

    mutating func makeAnonymous() {
        name = "Anonymous"
    }
}

Because it changes the property, Swift will only allow that method to be called on Person instances that are variables:

var person = Person(name: "Ed")
person.makeAnonymous()

5. Mutating methods - Additional

6. Properties and methods of strings

6. Properties and methods of strings
100 Days of Swift - Day 8 - 6. Properties and methods of strings

6. Properties and methods of strings

We’ve used lots of strings so far, and it turns out they are structs – they have their own methods and properties we can use to query and manipulate the string.

First, let’s create a test string:

let string = "Do or do not, there is no try."

You can read the number of characters in a string using its count property:

print(string.count)

They have a hasPrefix() method that returns true if the string starts with specific letters:

print(string.hasPrefix("Do"))

You can uppercase a string by calling its uppercased() method:

print(string.uppercased())

And you can even have Swift sort the letters of the string into an array:

print(string.sorted())

Strings have lots more properties and methods – try typing string. to bring up Xcode’s code completion options.

6. Properties and methods of strings - Additional

7. Properties and methods of arrays

7. Properties and methods of arrays
100 Days of Swift - Day 8 - 7. Properties and methods of arrays

7. Properties and methods of arrays

Arrays are also structs, which means they too have their own methods and properties we can use to query and manipulate the array.

Here’s a simple array to get us started:

var toys = ["Woody"]

You can read the number of items in an array using its count property:

print(toys.count)

If you want to add a new item, use the append() method like this:

toys.append("Buzz")

You can locate any item inside an array using its firstIndex() method, like this:

toys.firstIndex(of: "Buzz")

That will return 1 because arrays count from 0.

Just like with strings, you can have Swift sort the items of the array alphabetically:

print(toys.sorted())

Finally, if you want to remove an item, use the remove() method like this:

toys.remove(at: 0)

Arrays have lots more properties and methods – try typing toys. to bring up Xcode’s code completion options.

7. Properties and methods of arrays - Additional


이찬희 (MarkiiimarK)
Never Stop Learning.