This is the seventh day of my participation in the August More text Challenge. For details, see: August More Text Challenge

After writing a small and beautiful Swift framework: Then yesterday, a friend said that there was no source code parsing.

The core code of the Then framework is less than 80 lines, but it has got 3.5K star so far, which is really impressive.

So I feel that a great framework is not so much about how big it is, but about whether it actually solves a pain point and actually helps the developer.

Next, let’s take a look at this short framework.

Definition of the then() method

public protocol Then {}

extension Then where Self: AnyObject {

  /// Makes it available to set properties with closures just after initializing.
  ///
  /// let label = UILabel().then {
  /// $0.textAlignment = .center
  /// $0.textColor = UIColor.black
  /// $0.text = "Hello, World!"
  / / /}

  @inlinable
  public func then(_ block: (Self) throws -> Void) rethrows -> Self {
    try block(self)
    return self}}Copy the code

Break the above definition down into individual words:

AnyObject  

Is an empty protocol that all classes implement.

Can be placed in a WHERE statement to qualify as a class type. How to specify, will be mentioned below.

Self (lowercase s)

Self is divided into three situations:

  • Within the methodselfFor example, commonAttributes the self.And here’sselfRepresents concrete instances (class instances, structure instances, enumeration instances, and so on);
  • In a certaintypeAt the back of the.self, such asUILabel.selfWhich represents the type itself;
  • In a certainThe instanceYou can add it later.self, such aslabel.self, or the instance itself (which feels useless).

Self (capital S)

Self is often used in connection with a protocol, referring to the type that implements the protocol itself, as well as subtypes of that type.

In the above code, first look at Self in the extension:

extension Then where Self: AnyObject {}Copy the code

Among them:

  • whereUsed to specify constraints.
  • Self: AnyObjectAnd here’sSelfThat means implementationThenThe type of the protocol itself, or a subclass of that type.Self: AnyObjectThat means the current type needs to matchAnyObjectThe agreement.

Together, we extend types that implement the Then protocol and conform to the AnyObject protocol.

Look at Self appearing on the then method definition:

// I have removed "throws" and "rethrows" from the list
func then(_ block: (Self) - >Void) -> Self{}Copy the code

Among them:

  • Method is calledthen;
  • Receive a file namedblockThe parameter type is:(Self) -> VoidReceives a closure of typeSelf, the return value type isVoid;
  • The type of the returned value isSelf;

Self here also represents the type itself that implements the Then protocol, or the type of a subclass of that type.

With that explained above, let’s look at the code in its entirety:

extension Then where Self: AnyObject {
  @inlinable
  public func then(_ block: (Self) throws -> Void) rethrows -> Self {
    try block(self)
    return self}}Copy the code

That is, the type that implements the Then protocol and conforms to the AnyObject protocol is extended; We added a then method to the extension that accepts a closure of type (Self) -> Void and returns a value of the type itself (that is, Self). The block passed in from the outside is executed in the THEN method, and the current instance (that is, self) is returned.

Real World Example

Here’s a real world example:

let label = UILabel().then({ label in
    label.textAlignment = .center
    label.textColor = UIColor.black
    label.text = "Hello, World!"
})
Copy the code

Is equivalent to

let label = UILabel().then { label in
    label.textAlignment = .center
    label.textColor = UIColor.black
    label.text = "Hello, World!"
}
Copy the code

Is equivalent to the

let label = UILabel().then {
    $0.textAlignment = .center
    $0.textColor = UIColor.black
    $0.text = "Hello, World!"
}
Copy the code

First, the above three pieces of code are equivalent, but the code is gradually simplified.

The execution structure can be expressed as follows:

reference

Nominal Type