Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

215
Vistas
¿Por qué un método de mutación en un protocolo Swift recurre infinitamente a menos que solo sea un método de extensión?

Encontré el siguiente código en SR-142 en bugs.swift.org .

Si un protocolo tiene un método de extensión que está mutando, una instancia de clase puede llamar a la función de mutación sin ningún problema.

 // protocol definition protocol P { } extension P { mutating func m() { } } // class conforming to P class C : P { // redeclare m() without the mutating qualifier func m() { // call protocol's default implementation var p: P = self pm() } } let c = C() cm()

Si hago un pequeño cambio para agregar el método a la declaración del protocolo:

 protocol P { mutating func m() // This is what I added. } extension P { mutating func m() { } } class C : P { func m() { var p: P = self pm() } } let c = C() cm() // This one is calling itself indefinitely; why?

¿Por qué cm() sigue llamándose a sí mismo una y otra vez?

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Con su cambio en el segundo ejemplo, al incluir la m en la definición del protocolo, eso le indica a Swift que emplee despacho dinámico. Entonces, cuando llama a pm() , determina dinámicamente si el objeto ha anulado la implementación predeterminada del método. En este ejemplo particular, eso da como resultado que el método se llame recursivamente a sí mismo.

Pero en el primer ejemplo, a falta de que el método forme parte de la definición del protocolo, Swift empleará el envío estático y, dado que p es del tipo P , llamará a la implementación m en P


A modo de ejemplo, considere dónde el método no forma parte de la definición del protocolo (y, por lo tanto, no está en la "tabla de testigos del protocolo"):

 protocol P { // func method() } extension P { func method() { print("Protocol default implementation") } } struct Foo: P { func method() { print(“Foo implementation") } }

Debido a que foo es una referencia P y porque el method no es parte de la definición P , excluye el method de la tabla testigo del protocolo y emplea el envío estático. Como resultado, lo siguiente imprimirá “Implementación predeterminada del protocolo”:

 let foo: P = Foo() foo.method() // Protocol default implementation

Pero si cambia el protocolo para incluir explícitamente este método, dejando todo lo demás igual, el method se incluirá en la tabla testigo del protocolo:

 protocol P { func method() }

Luego, lo siguiente ahora imprimirá "Implementación de Foo", porque aunque la variable foo es de tipo P , determinará dinámicamente si el tipo subyacente, Foo , ha anulado ese método:

 let foo: P = Foo() foo.method() // Foo implementation

Para obtener más información sobre el envío dinámico frente al estático, consulte el video WWDC 2016Comprender el rendimiento de Swift .

over 4 years ago · Santiago Trujillo Denunciar

0

Al declarar m en el protocolo y proporcionar la implementación en su clase, sobrescribe la implementación predeterminada.

Pero en el primer ejemplo, cuando lanza su clase como protocolo, llamará a la implementación predeterminada del protocolo porque la implementación de la clase es propia y no sobrescribe ninguno de los métodos del protocolo.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda