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

214
Vistas
Why does a mutating method in a Swift protocol infinitely recurse unless only an extension method?

I came across the following code in SR-142 on bugs.swift.org.

If a protocol has an extension method that's mutating, a class instance can call the mutating function without any problem.

// 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 
        p.m()
    }
}

let c = C()
c.m()

If I make a small change to add the method to the protocol declaration:

protocol P {
  mutating func m()  // This is what I added.
}

extension P { 
  mutating func m() { } 
}

class C : P { 
  func m() { 
    var p: P = self 
    p.m() 
  }
}

let c = C() 
c.m()         // This one is calling itself indefinitely; why?

Why does c.m() keep calling itself again and again?

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

0

With your change in the second example, by including the m in the protocol definition, that instructs Swift to employ dynamic dispatch. So when you call p.m(), it dynamically determines whether the object has overridden the default implementation of the method. In this particular example, that results in the method recursively calling itself.

But in the first example, in the absence of the method being part of the protocol definition, Swift will employ static dispatch, and because p is of type P, it will call the m implementation in P.


By way of example, consider where the method is not part of the protocol definition (and therefore not in the “protocol witness table”):

protocol P {
    // func method()
}

extension P {
    func method() {
        print("Protocol default implementation")
    }
}

struct Foo: P {
    func method() {
        print(“Foo implementation")
    }
}

Because the foo is a P reference and because method is not part of the P definition, it excludes method from the protocol witness table and employs static dispatch. As a result the following will print “Protocol default implementation”:

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

But if you change the protocol to explicitly include this method, leaving everything else the same, method will be included in the protocol witness table:

protocol P {
    func method()
}

Then the following will now print “Foo implementation”, because although the foo variable is of type P, it will dynamically determine whether the underlying type, Foo, has overridden that method:

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

For more information on dynamic vs static dispatch, see WWDC 2016 video Understanding Swift Performance.

over 4 years ago · Santiago Trujillo Denunciar

0

By declaring m in the protocol & providing implementation in your class, it over writes the default implementation.

But in the first example when you cast your class as protocol it will call protocol's default implementation because the implementation of the class is it own and not over writing any of the protocol's method

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