Memberwise Initializers for Structure Types

⋅ 4 min read ⋅ Swift Initialization Struct

Table of Contents

Struct is one of the basic building blocks in your app. Today I'm going to share some tips about memberwise Initializers.

Default Memberwise Initializers

If you don't define any custom initializers on your struct, it will automatically receive memberwise initializer. The memberwise initializer contains all the members of that struct.

If you declare your Struct like this:

struct User {
let firstName: String
let middleName: String?
let lastName: String
}

Without the need to declare init, you can initialize it like this:

let user = User(firstName: "John", middleName: nil, lastName: "Doe")

You get this for free, and this might suit your needs most of the time.

You can easily support sarunw.com by checking out this sponsor.

Sponsor sarunw.com and reach thousands of iOS developers.

Not all member creates equal

There might be a time where you don't need every property to be set (middleName in this case), you may want something like this:

let user = User(firstName: "John", lastName: "Doe")

Too bad you will get this error:

Missing argument for parameter 'middleName' in call

There are many ways to tackle this problem.

Default Parameter Values

The first one is using one feature of Swift Fuction, Default Parameter Values.

From Swift Document:

You can define a default value for any parameter in a function by assigning a value to the parameter after that parameter’s type. If a default value is defined, you can omit that parameter when calling the function.

You declare .init and define a default value to a parameter you want to omit. I want to omit middleName in this case, so I set the default value to nil.

struct User {
let firstName: String
let middleName: String?
let lastName: String

init(firstName: String, middleName: String? = nil, lastName: String) {
self.firstName = firstName
self.middleName = middleName
self.lastName = lastName
}
}

Try to initialize User object again, and the error is gone.

let user = User(firstName: "John", middleName: "D", lastName: "Doe")
let user = User(firstName: "John", lastName: "Doe")

The downside of this method is you have to create a custom initializer for your struct and lose all the benefit of the memberwise initializer. You have to type every property in the struct in your custom initializer. This can be tiresome, so here come the second solution.

Default Property Values

In Swift 5.1, you can set default value into a property, and memberwise initializer will be generated with a default parameter set. Just like the one we manually did in the previous solution.

struct User {
let firstName: String
var middleName: String? = nil
let lastName: String
}

Define a default value for a property like this would generate the following memberwise initializer.

// The generated memberwise init:
init(firstName: String, middleName: String? = nil, lastName: String) {
self.firstName = firstName
self.middleName = middleName
self.lastName = lastName
}

This will save you a lot of keystrokes if you have a lot of properties. The only difference here is you have to declare middleName as var instead of let.

But, I want it to be let

If you want your middle name to be let (It doesn't change that often right?), you have no choice other than using Default Parameter Values. To save some keystroke, you can use Xcode "Generate memberwise initializer" shortcut.

⌘ - command + click (based on your preference, it might be ⌃ – Control + ⌘ - command + click) on your struct and select Generate memberwise initializer.

Generate memberwise initializer
Generate memberwise initializer

or

Click on your struct, then Editor Menu > Refactor > Generate memberwise initializer.

or

Right-click on your struct, then Refactor > Generate memberwise initializer.

Generate memberwise initializer
Generate memberwise initializer

And you will get this without any typing.

Generated memberwise initializer
Generated memberwise initializer

The only thing you need to do is change the scope and assign a default value to middleName parameter.

struct User {
init(firstName: String, middleName: String? = nil, lastName: String) {
self.firstName = firstName
self.middleName = middleName
self.lastName = lastName
}

let firstName: String
let middleName: String?
let lastName: String
}

You can easily support sarunw.com by checking out this sponsor.

Sponsor sarunw.com and reach thousands of iOS developers.

Read more article about Swift, Initialization, Struct, or see all available topic

Enjoy the read?

If you enjoy this article, you can subscribe to the weekly newsletter.
Every Friday, you'll get a quick recap of all articles and tips posted on this site. No strings attached. Unsubscribe anytime.

Feel free to follow me on Twitter and ask your questions related to this post. Thanks for reading and see you next time.

If you enjoy my writing, please check out my Patreon https://www.patreon.com/sarunw and become my supporter. Sharing the article is also greatly appreciated.

Become a patron Buy me a coffee Tweet Share
Previous
How to display HTML in UILabel and UITextView

When you work with an API, there would be a time when your backend wants to control a text style, and HTML is the most common format for the job. Do you know that WKWebView is not the only way to present HTML string? Learn how to render it in UILabel and UITextView.

Next
How to preserve a struct memberwise initializer when you have a custom initializer

A tip to declare a custom initializer without losing a memberwise initializer.

← Home