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

437
Vistas
¿Por qué mi estructura se vuelve inmutable en una cadena de métodos?

En Swift, estoy tratando de implementar un método "toque" similar al método que existe en Ruby.

Se me ocurrió el siguiente código de ejemplo:

 private protocol Tap { mutating func tap(_ block: (inout Self) -> Void) -> Self } private extension Tap { mutating func tap(_ block: (inout Self) -> Void) -> Self { block(&self) return self } } extension Array: Tap {} var a = Array(repeating: "Hello", count: 5) a.tap { $0.append("5") }.tap { $0.append("7") } print(a) // (Expected) => ["Hello", "Hello", "Hello", "Hello", "Hello", "5", "7"]

No estoy muy familiarizado con las funciones de mutación, los parámetros de entrada y salida o Swift en general, pero parece que el código anterior debería funcionar para mí. tap funciona como se esperaba cuando no se incluye en una cadena de métodos. Cuando lo incluyo como parte de una cadena de métodos, como en el ejemplo anterior, el compilador de Swift se queja:

No se puede usar un miembro mutante en un valor inmutable: la llamada a la función devuelve un valor inmutable

¿Alguien puede explicarme por qué esto no funciona? ¿Alguien puede proporcionar una solución funcional y explicar por qué funciona esa solución?

Editar:

Otro ejemplo de uso sería:

 let user = User(fromId: someId).tap { $0.firstName = someFirstName $0.lastName = someLastName }

tap es una cosa de conveniencia que viene de Ruby. Estoy principalmente interesado en entender por qué los tipos en mi función no funcionan bien.

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

0

El return self devuelve una copia de la matriz original, no la matriz original en sí. Hasta que esta copia se almacene como var , no se puede mutar. Entonces, esto funcionaría:

 var b = a.tap { $0.append("5") } b.tap { $0.append("7") }

Pero no sin almacenar b como var primero. Por supuesto, no crearías una b en primer lugar, solo usarías a repetidamente como ya lo indicaste.

Entonces, el problema es que puede realizar un tap una vez, pero no puede encadenar tap . Esto se debe a que el retorno de self es implícitamente inmutable y no puede llamar a una función de mutación en un valor inmutable. Cambiar tap a una función sin mutación podría darte lo que quieres:

 private extension Tap { func tap(_ block: (inout Self) -> Void) -> Self { let copy = self block(&copy) return copy } } var a = Array(repeating: "Hello", count: 5) a = a.tap({$0.append("5")}).tap({$0.append("7")})

Debido a que cada invocación de tap( devuelve una copia del original modificado por el bloque dado, puede llamarlo en tipos inmutables. Eso significa que puede encadenar.

El único inconveniente es que la nueva a = al principio.

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