One, foreword

In the previous article “Keyword Designated, Convenience, Required”, we learned about the new features brought by Swift in the constructor. Combined with our previous article “Brief Analysis of Struct and Class”, Today we’re going to talk about the difference between structs and classes.

The default constructor

First, a soul-searching question: What is a “default constructor”?

Constructors (constructors) are not explicitly defined and are automatically added by the system! (In Swift, the default constructor is the Designated constructor.)

Is it difficult to understand just by reading the words? I’ll do a demo.

2.1, struct

struct DemoStruct {
    var name: String
    var age: Int
}
Copy the code

There is no constructor (init), but we can use it like this:

When we type “open parenthesis”, Xcode automatically prompts us, giving us a unique initialization method. This is the “default constructor”, which we can also create explicitly like this:

That’s through the init constructor, but again, Xcode tells us that we have two arguments. Why have arguments instead of no arguments, e.g. Demostruct.init ()?

2.1.1. Member by member constructor

This is the Swift specification: When we don’t explicitly specify at least one init constructor, Swift adds a default constructor for us, whose inputs are all the members of the struct!

In the example above, we define two members, name and age, so Swift will include them in the default constructor from top to bottom, creating the following constructor:

Wouldn’t it be boring if struct ended at this point? If you think that’s it, you’re Too Young Too Simple!

If we have a struct with a lot of member variables, swift will create a default constructor for us, but we need to pass in every parameter when we use it, so it’s a bit of a hassle. Is there another way? For example, when initializing, I just want to pass name:

The above snippet has no errors and runs without any problems!

We have three solutions:

  • Optional default constructor;
  • Default argument Default constructor;
  • Extension constructor;

2.1.2. Optional default constructor

We see that age is of type Int, right? , but can be nil; Therefore, we can enforce the necessary parameters only by passing them in during initialization:

2.1.3 Default Parameters Default constructor

The name is a little convoluted, but the effect is simple:

2.1.4. Extend the constructor

Extension, also known as extension, is a method provided by Swift that can be used by both structs and classes:

Init (name: String) {self.init(name: name, age: 18)}}Copy the code

The result is as follows:

2.2, class

Once again, define a class as follows:

class DemoClass {
    var name: String
    var age: Int
}
Copy the code

If this is all, Xcode will immediately prompt an error (the class has no constructor) :

The explicit Designated constructor is required. For DemoClass, the explicit Designated constructor is defined as the struct’s one-by-one constructor. An error will be reported if only a partial constructor is constructed:

This error indicates that all members are not initialized. There are three ways to do this:

  • Set age to nil by default (equivalent to 2.1.2);
  • Age is defined with a default value (equivalent to 2.1.3);
  • Give default values in the constructor (as shown in the following code);
Class DemoClass {var name: String var age: Int init(name: String) {self.name = name // constructor given default self.age = -1}}Copy the code

Class requires that a constructor be explicitly specified, whereas structs are added automatically by Swift. Similarly, a class can be extended to override the constructor by adding the keyword “convenience” :

extension DemoClass {
    convenience init(name: String, age: Int) {
        self.init(name: name)
        self.age = age
    }
}
Copy the code

Let’s take a look at the result:

Failable constructor

Similar to Kotlin, there is a type called nullable. Swift also has nullable types, and Swift goes a step further by allowing null objects (i.e., nil if creation fails) to be returned when a variable (struct), object (class), or enumeration is created.


Note: according to the official documentation, it clearly states that only s t r u c t , c l a s s , e n u m Can be returned at creation time n i l ! \color{red}{struct, class, enum (struct, class, enum); }

  • What is an empty type?
Var variable: T? Var variable: T? = nill // example: var STR: String? Var num: Int? = nil // Nil integer typeCopy the code
  • How do I define a failable constructor?

The failable constructor definition is as simple as adding a question mark after init: init? For example:

As you can see, we’ve defined a failable constructor that returns nil if the string passed as “empty string” when creating Person, otherwise the creation succeeds. From the figure above, we can also see that the return type of the failable constructor is: T? In the above example, the return type is Person? , which means that it could be nil.

Above is our test code, which prints out very clearly after execution. I’m not going to show you class or enum, like struct, but you can test it yourself.

Iv. Personal Reflections

But some friends ask: why spend so much effort to analyze structs and classes? Is it because Swift added structs?

No, because WHEN I was working on iOS Swift5 from 0 to 1 series, I found that whenever I implemented some features, I more or less involved some new features of Swift. Although these features have been available since Swift came out, I am not sure that everyone is familiar with them. Therefore, Whenever new knowledge points in Swift are involved, I will open some branch series to explain and analyze them in advance, hoping that everyone can learn and absorb them bit by bit, rather than I throw out a lot of new knowledge points at once, which will make it difficult for everyone to digest and absorb and affect their mood and give up halfway.

Swift is actually very simple, I hope to let everyone grow and progress together with me, and also can communicate happily. Moreover, in my blog, all articles are of high quality and can be absorbed (no matter iOS, Java, Android or H5). Therefore, I will explain the main line and intersperses different branches. At the same time, it takes a few days to write a quality blog post (even a branch post), so don’t rush.

Thank you very much!