Swift 3.0 extension of basic learning

  • 2020-05-24 06:18:06
  • OfStack

introduce

Extensions can add new functionality for classes, structs, enums, and protocols. Includes the ability to extend types that do not have source code access. Extensions are similar to the concept of Objective-C classification. Unlike the classification of Objective-C, the Swift extension has no name.

In Swift, the extension can do this:

Add the instance property of the calculation and the type property of the calculation Define instance methods and type methods Provide a new initializer Define the subscript Define and use the new nested type Make the existing type conform to the protocol

It is important to note that extensions can add functionality to a type, but they cannot override existing functionality.

Extended syntax

Define extensions using the keyword extension:


extension SomeType {
 // new functionality to add to SomeType goes here
}

Extensions can extend an existing type to accommodate one or more protocols:


extension SomeType: SomeProtocol, AnotherProtocol {
 // implementation of protocol requirements goes here
}

Calculate attribute

Extensions can add compute instance properties and compute type properties to existing types:


extension Double {
 var km: Double { return self * 1_000.0 }
 var m: Double { return self }
 var cm: Double { return self / 100.0 }
 var mm: Double { return self / 1_000.0 }
 var ft: Double { return self / 3.28084 }
}
let oneInch = 25.4.mm
print("One inch is \(oneInch) meters")
// Prints "One inch is 0.0254 meters"
let threeFeet = 3.ft
print("Three feet is \(threeFeet) meters")
// Prints "Three feet is 0.914399970739201 meters"

Since these properties are read-only computed properties, they do not need to include the keyword get.

Can be directly calculated:


let aMarathon = 42.km + 195.m
print("A marathon is \(aMarathon) meters long")
// Prints "A marathon is 42195.0 meters long"

It is important to note that extensions can add new compute properties, but they cannot add storage properties, or add property observers to existing properties.

The initializer

Extensions can add new convenience initializers to a class, but they cannot add a new specified initializer to a class or uninitialize it. The specified initializer and uninitializer must always be provided by the original class implementation.

The following structures are defined:


struct Size {
 var width = 0.0, height = 0.0
}
struct Point {
 var x = 0.0, y = 0.0
}
struct Rect {
 var origin = Point()
 var size = Size()
}

Here's how to create an Rect instance (see the article about the initialization section of the default initializer) :


let defaultRect = Rect()
let memberwiseRect = Rect(origin: Point(x: 2.0, y: 2.0),
       size: Size(width: 5.0, height: 5.0))

At this point, we can extend the Rect structure to add a new initializer:


extension Rect {
 init(center: Point, size: Size) {
  let originX = center.x - (size.width / 2)
  let originY = center.y - (size.height / 2)
  self.init(origin: Point(x: originX, y: originY), size: size)
 }
}

Then we can use the new initialization method to create the instance:


let centerRect = Rect(center: Point(x: 4.0, y: 4.0),
      size: Size(width: 3.0, height: 3.0))
// centerRect's origin is (2.5, 2.5) and its size is (3.0, 3.0)

methods

Here's how to add a method called repetitions to the Int type:


extension Int {
 func repetitions(task: () -> Void) {
  for _ in 0..<self {
   task()
  }
 }
}

Then we can call this method like this:


3.repetitions {
 print("Hello!")
}
// Hello!
// Hello!
// Hello!

Variation instance method

An extended instance method can also modify (or mutate) the instance itself. Modifying the structure of self or its properties and the enumeration method must mark the instance method as mutating, just like mutating method 1 in the original implementation.

Here's an example:


extension SomeType: SomeProtocol, AnotherProtocol {
 // implementation of protocol requirements goes here
}
0

The subscript

Want to achieve

123456789 [0] to return to 9 123456789 return to 8 [1]

The code is as follows:


extension SomeType: SomeProtocol, AnotherProtocol {
 // implementation of protocol requirements goes here
}
1

If the subscript is out of bounds, return 0:


extension SomeType: SomeProtocol, AnotherProtocol {
 // implementation of protocol requirements goes here
}
2

Nested types

Extension to add nested types:


extension Int {
 enum Kind {
  case negative, zero, positive
 }
 var kind: Kind {
  switch self {
  case 0:
   return .zero
  case let x where x > 0:
   return .positive
  default:
   return .negative
  }
 }
}

Nested types can now be used in any Int value:


extension SomeType: SomeProtocol, AnotherProtocol {
 // implementation of protocol requirements goes here
}
4

Reference:
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Extensions.html#//apple_ref/doc/uid/TP40014097-CH24-ID151

conclusion


Related articles: