Swift Extensión

Una extensión agrega nueva funcionalidad a un tipo de clase, estructura o enumeración existente.

Las extensiones pueden agregar nueva funcionalidad a un tipo, pero no pueden sobrescribir la funcionalidad existente.

Las extensiones en Swift pueden:

  • Agregar propiedades calculadas y propiedades estáticas calculadas
  • Definir métodos de instancia y métodos de tipo
  • Proporcionar nuevos inicializadores
  • Definir subíndices
  • Definir y usar nuevos tipos anidados
  • Hacer que un tipo existente se ajuste a un protocolo

Sintaxis

La declaración de extensión usa la palabra claveextension:

extension SomeType {
    // 加到SomeType的新功能写到这里
}

Una extensión puede extender un tipo existente para que pueda adaptarse a uno o más protocolos, la sintaxis es la siguiente:

extension SomeType: SomeProtocol, AnotherProctocol {
    // 协议实现写到这里
}

Propiedades calculadas

Las extensiones pueden agregar propiedades de instancia calculadas y propiedades de tipo calculadas a tipos existentes.

Ejemplo

El siguiente ejemplo agrega 5 propiedades de instancia calculadas al tipo Int y amplía su funcionalidad:

extension Int {
   var add: Int {return self + 100 }
   var sub: Int { return self - 10 }
   var mul: Int { return self * 10 }
   var div: Int { return self / 5 }
}
    
let addition = 3.add
print("加法运算后的值:\(addition)")
    
let subtraction = 120.sub
print("减法运算后的值:\(subtraction)")
    
let multiplication = 39.mul
print("乘法运算后的值:\(multiplication)")
    
let division = 55.div
print("除法运算后的值: \(division)")

let mix = 30.add + 34.sub
print("混合运算结果:\(mix)")

El resultado de ejecutar el programa anterior es:

加法运算后的值:103
减法运算后的值:110
乘法运算后的值:390
除法运算后的值: 11
混合运算结果:154

Inicializadores

Las extensiones pueden agregar nuevos inicializadores a tipos existentes.

Esto te permite extender otros tipos, usar tus propios tipos personalizados como parámetros de inicializador, o proporcionar opciones de inicialización adicionales que no estaban incluidas en la implementación original del tipo.

Las extensiones pueden agregar nuevos inicializadores de conveniencia init() a las clases, pero no pueden agregar nuevos inicializadores designados ni destructores deinit() a las clases.

struct sum {
    var num1 = 100, num2 = 200
}

struct diff {
    var no1 = 200, no2 = 100
}

struct mult {
    var a = sum()
    var b = diff()
}


extension mult {
    init(x: sum, y: diff) {
        _ = x.num1 + x.num2
        _ = y.no1 + y.no2
    }
}


let a = sum(num1: 100, num2: 200)
let b = diff(no1: 200, no2: 100)

let getMult = mult(x: a, y: b)
print("getMult sum\(getMult.a.num1, getMult.a.num2)")
print("getMult diff\(getMult.b.no1, getMult.b.no2)")

El resultado de ejecutar el programa anterior es:

getMult sum(100, 200)
getMult diff(200, 100)

Métodos

Las extensiones pueden agregar nuevos métodos de instancia y métodos de tipo a tipos existentes.

El siguiente ejemplo agrega un nuevo método de instancia llamado topics al tipo Int:

extension Int {
   func topics(summation: () -> ()) {
      for _ in 0..<self {
         summation() 
      }
   }
}  

4.topics({
   print("扩展模块内")       
})    
    
3.topics({
   print("内型转换模块内")       
})  

El resultado de ejecutar el programa anterior es:

Dentro del módulo de extensión  
Dentro del módulo de extensión  
Dentro del módulo de extensión  
Dentro del módulo de extensión  
Dentro del módulo de conversión de tipo interno  
Dentro del módulo de conversión de tipo interno  
Dentro del módulo de conversión de tipo interno

Estetopicsmétodo utiliza un() -> ()parámetro único de tipo, lo que indica que la función no tiene parámetros y no tiene valor de retorno.

Después de definir esta extensión, puedes invocar sobre cualquier enterotopicsal método, cuya función es ejecutar una tarea varias veces:


Métodos de instancia mutables

Los métodos de instancia agregados mediante una extensión también pueden modificar la propia instancia.

Los métodos que modifican self o sus propiedades en tipos de estructura y enumeración deben marcarse como mutating, al igual que los métodos modificadores de la implementación original.

Ejemplo

El siguiente ejemplo agrega un nuevo método modificador llamado square al tipo Double de Swift, para calcular el cuadrado de un valor original:

extension Double {
   mutating func square() {
      let pi = 3.1415
      self = pi * self * self
   }
}

var Trial1 = 3.3
Trial1.square()
print("圆的面积为: \(Trial1)")


var Trial2 = 5.8
Trial2.square()
print("圆的面积为: \(Trial2)")


var Trial3 = 120.3
Trial3.square()
print("圆的面积为: \(Trial3)")

El resultado de ejecutar el programa anterior es:

圆的面积为: 34.210935
圆的面积为: 105.68006
圆的面积为: 45464.070735

Subíndices

Las extensiones pueden agregar nuevos subíndices a un tipo existente.

Ejemplo

El siguiente ejemplo agrega un subíndice entero al tipo Int incorporado de Swift. Este subíndice [n] devuelve el dígito decimal

extension Int {
    subscript(multtable: Int) -> Int {
        var powerOf10 = 1
        var index = multtable
        while index > 0 {
            powerOf10 *= 10
            index -= 1
        }
        return (self / powerOf10) % 10
    }
}

print(12[0])     // 输出:2
print(7869[1])   // 输出:6
print(786543[2]) // 输出:5

El resultado de ejecutar el programa anterior es:

2
6
5

Tipos anidados

Las extensiones pueden agregar nuevos tipos anidados a clases, estructuras y enumeraciones existentes:

extension Int {
   enum calc
   {
      case add
      case sub
      case mult
      case div
      case anything
   }

   var print: calc {
      switch self
      {
         case 0:
            return .add
         case 1:
            return .sub
         case 2:
            return .mult
         case 3:
            return .div
         default:
            return .anything
       }
   }
}

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

      }
   }
}

result([0, 1, 2, 3, 4, 7])

El resultado de ejecutar el programa anterior es:

 10 
 20 
 30 
 40 
 50 
 50 
Otras extensiones