Swift for iOS Development (13)-Extension

version

Xcode 11.3.1
Swift 5.1.3

Expand

Extensions can add new functions to an existing class, structure, enumeration, and protocol, but cannot rewrite existing functions.
Extensions in Swift can:

  • Add calculated attributes (stored attributes cannot be added)
  • Define instance methods and class methods
  • Provide a new constructor
  • Define subscript
  • Define and use new nested types
  • Make an existing type conform to a certain protocol

grammar

extension SomeType {
  // 在这里给 SomeType 添加新的功能
}

Calculated attributes

Extensions can add calculated instance attributes and calculated class attributes to existing types.
1. Calculated instance attributes

extension Int {
    
    var add: Int {
        return self + 10
    }
    
    var sub: Int {
        return self - 10
    }
}

let addition = 15.add
let substraction = 15.sub
print(addition, substraction)
// 25 5

2. Calculated class attributes

struct AA {
    static var num = 10
}

extension AA {
    static var aad: Int {
        return self.num + 10
    }
}

let aa = 5.add
print(aa)
// 15

As mentioned before, extensions cannot add stored attributes. For example, in the above example, adding the following extension to the class attribute num of AA will cause a compilation error:

    static var num: Int {
        return self.num + 10
    }

method

Extensions can add new instance methods and class methods to existing types.
1. Example method

class Counter {
    
    var count = 0
}

extension Counter {
    func increment() -> Int {
        return count + 1
    }
}

let counter = Counter()
let currentCount = counter.increment()
print(currentCount)
// 1

2. Class methods

extension Int {
    static func printFunc() {
        print("我被打印了")
    }
}

Int.printFunc()
// 我被打印了

Constructor

Extensions can add new constructors to existing types.
Extensions can add new convenience initializers to the class, but they cannot add new designated initializers or deinit() to the class.

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()
}

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)
    }
}

let centerRect = Rect(center: Point(x: 5.0, y: 5.0), size: Size(width: 4.0, height: 4.0))
print(centerRect.origin)
// Point(x: 3.0, y: 3.0)

Because the Rect structure provides default values ​​for all attributes (origin and size), it automatically obtains a default constructor and a member constructor. These constructors can be used to create new Rect instances.
This new constructor first calculates an appropriate origin based on the provided center and size. Then this constructor calls the member constructor init(origin:size:) that comes with the structure, which stores the new origin and size values ​​in the appropriate attributes.

Subscript

Extensions can add new subscripts to existing types.
In the following example, an integer subscript is added to the Int type of Swift. The subscript [n] starts from the right side of the number and returns to the nth place after the decimal point:

extension Int {
    subscript(digitIndex: Int) -> Int {
        var decimalBase = 1
        for _ in 0..<digitIndex {
            decimalBase *= 10
        }
        return (self / decimalBase) % 10
    }
}

print(123[0])
// 3
print(123[1])
// 2
print(123[2])
// 1

Nested type

Extensions can add new nested types to existing classes, structures, and enumerations:

extension Int {
    
   enum calculate
   {
      case add
      case sub
      case mult
   }

   var print: calculate {
      switch self
      {
         case 0:
            return .add
         case 1:
            return .sub
         default:
            return .mult
       }
   }
}

func result(numb: [Int]) {
   for i in numb {
      switch i.print {
         case .add:
            print("10")
          case .sub:
            print("20")
         case .mult:
            print("30")

      }
   }
}

result(numb: [1, 2, 0])
/**
 20
 30
 10
 */

Guess you like

Origin blog.csdn.net/u012078168/article/details/104561938