Cada vez que Apple presenta una versión nueva de Swift, la lista de novedades incluye términos que hasta hace poco se asociaban a Rust: tipos que no se pueden copiar, propiedad única de los valores, préstamos de memoria, comprobación de carreras de datos en compilación. De ahí la pregunta que circula entre desarrolladores: ¿se está convirtiendo Swift en el Rust de Apple? La respuesta corta es que se parece más cada año en las herramientas, pero no en la filosofía. Conviene repasar qué ha llegado, qué sigue siendo distinto y por qué Apple lo hace.
El punto de partida: ARC y seguridad por defecto
Swift nació en 2014 como un lenguaje seguro de alto nivel. Su modelo de memoria se basa en el recuento automático de referencias (ARC): el compilador inserta las operaciones de retención y liberación, y los valores (struct, enum) se copian con semántica de valor, a menudo con copia diferida. Es cómodo y evita la mayoría de los errores de memoria clásicos, pero tiene costes: contadores atómicos, asignaciones en el montículo y ciclos de referencias que el programador debe romper con weak o unowned.
Rust resuelve el mismo problema de otra manera. No hay recolector ni contadores por defecto: la propiedad y los préstamos se verifican en compilación, y el coste en ejecución es nulo. La diferencia clave es cuándo se decide quién posee un valor: en Rust, en compilación y de forma obligatoria; en Swift, tradicionalmente en ejecución y de forma implícita.
Qué ha incorporado Swift en estos años
Tipos no copiables y propiedad explícita
Swift 5.9 introdujo ~Copyable, la forma de declarar que un tipo tiene un único propietario. Swift 6 amplió el soporte a contextos genéricos y a tipos de la biblioteca estándar como Optional y Result. Junto a ello llegaron los modificadores borrowing y consuming para los parámetros y el operador consume para terminar de forma explícita la vida de una variable. El ejemplo típico es un recurso del sistema que se cierra solo cuando desaparece su dueño:
struct Archivo: ~Copyable {
private let descriptor: Int32
init(descriptor: Int32) { self.descriptor = descriptor }
deinit { close(descriptor) } // se cierra al perder el dueño
borrowing func leer() { /* solo lectura, sin tomar posesión */ }
consuming func cerrar() { /* el llamador pierde el valor */ }
}
let a = Archivo(descriptor: abrir())
a.leer()
a.cerrar()
// a.leer() // error de compilación: 'a' ya se consumió
El equivalente en Rust es tan natural que casi no hace falta escribirlo (mover un valor lo consume por defecto), pero muestra la correspondencia:
struct Archivo { fd: i32 }
impl Drop for Archivo {
fn drop(&mut self) { /* close(self.fd) */ }
}
impl Archivo {
fn leer(&self) {} // préstamo inmutable
fn cerrar(self) {} // consume el valor
}
La diferencia es de punto de partida. En Rust todo es movible y no copiable salvo que se implemente Copy; en Swift todo es copiable salvo que se escriba ~Copyable. La propiedad es una opción para el código que la necesita, no una regla que atraviesa todo el lenguaje.
Swift 6.4: la propiedad pasa de curiosidad a biblioteca
La señal más clara de que esta línea va en serio está en Swift 6.4, publicada el 15 de septiembre de 2026. Según las notas oficiales, incluye UniqueBox (un puntero en el montículo con propiedad única y sin recuento de referencias), UniqueArray (un array para elementos no copiables sin copia diferida), Ref y MutableRef como contenedores para prestar o mutar un valor, accesores borrow y mutate, y la posibilidad de que los tipos no copiables sean Equatable, Comparable y Hashable. También se añade el protocolo Iterable, que permite recorrer elementos prestándolos en lugar de copiarlos. Son, en la práctica, los equivalentes de Box, Vec, las referencias y los iteradores de Rust, con nombres propios.
Datos compartidos: concurrencia sin carreras
Swift 6 (septiembre de 2024) añadió un modo de lenguaje que convierte las posibles carreras de datos en errores de compilación, con Sendable y aislamiento por actores. Es la respuesta de Swift al Send/Sync de Rust: la seguridad ante hilos verificada por el compilador. La migración resultó dolorosa para muchos proyectos, y Swift 6.2 (septiembre de 2025) la suavizó con la «concurrencia accesible»: aislamiento por defecto al actor principal si se activa, y @concurrent para marcar el trabajo que sí debe ejecutarse en paralelo. En Rust no existe ese «modo»: el modelo es obligatorio desde el primer día.
Span, InlineArray y memoria segura sin punteros
Swift 6.2 introdujo Span (acceso seguro a memoria contigua con validez comprobada en compilación y sin coste en ejecución) e InlineArray (arrays de tamaño fijo con almacenamiento en línea, que pueden vivir en la pila). A ello se suma una opción de seguridad de memoria estricta que señala las construcciones inseguras. En Swift 6.4 Span se convierte directamente a std::span de C++20, un detalle relevante para la interoperabilidad. Son los equivalentes de los slices y los arrays de longitud fija de Rust.
Swift incrustado y fuera del ecosistema Apple
Embedded Swift es un subconjunto del lenguaje que genera binarios pequeños e independientes del runtime, pensado para microcontroladores. En la 6.4 admite tipos existenciales (any Protocol) y capturar errores de cualquier tipo, además de un aviso EmbeddedRestrictions. Swift 6.2 añadió compilación a WebAssembly, y Swift 6.3 (24 de marzo de 2026) trajo el primer SDK oficial para Android, con interoperabilidad con Kotlin y Java. Todo esto lo coloca, por primera vez, en el terreno que Rust ocupaba casi en solitario: sistemas, firmware y código multiplataforma.
Qué sigue siendo distinto
Aspecto | Swift | Rust |
Gestión de memoria por defecto | ARC (en ejecución) | Propiedad y préstamos (en compilación) |
Copia por defecto | Sí, salvo | No, salvo |
Seguridad ante hilos | Modo de lenguaje Swift 6, con ajustes | Obligatoria ( |
Ciclos de referencias | Posibles; hay que usar | Posibles solo con |
Lifetimes explícitos | No (inferencia de alcance) | Sí, cuando hace falta |
Dueño del lenguaje | Apple (proceso abierto) | Fundación Rust |
Terreno principal | Apps y sistemas Apple | Sistemas y software de infraestructura |
Swift mantiene la filosofía de la «revelación progresiva de la complejidad»: el código habitual se escribe sin pensar en propiedad, y las herramientas de bajo nivel están ahí para quien las necesita. Rust hace lo contrario: obliga a pensar en ella desde la primera línea y recompensa con garantías estáticas. Por eso las posibilidades de ciclos de referencias y el coste de ARC siguen existiendo en Swift, aunque el código de rendimiento crítico pueda evitarlos.
Por qué Apple va en esta dirección
Hay tres razones que se refuerzan entre sí. La primera es la seguridad: Apple presentó en septiembre de 2025 Memory Integrity Enforcement, una protección activa de forma permanente que combina hardware (la extensión de etiquetado de memoria mejorada, EMTE) con asignadores seguros en el iPhone 17 y el iPhone Air, y la define como el resultado de unos cinco años de trabajo. Ese enfoque reconoce que los errores de memoria en C y C++ siguen siendo el principal problema, y que la defensa es reducir su superficie con lenguajes seguros además de mitigarlos en hardware.
La segunda es la reescritura incremental. En junio de 2026, Swift.org describió cómo Apple migró de C a Swift el intérprete de hinting de fuentes TrueType, con un rendimiento aproximadamente un 13 % mejor según ese relato. El caso importa por el método: sustituir código crítico en el sistema sin reescribirlo todo, apoyado en la interoperabilidad con C y C++, que cada versión de Swift mejora (la 6.3 añadió el atributo @c para implementar en Swift funciones visibles desde C).
La tercera es la competencia por el terreno de los sistemas. Con Rust entrando en el kernel de Linux, en Android y en Windows, un lenguaje propio que no pueda ofrecer rendimiento predecible ni uso sin runtime queda limitado a las aplicaciones. Los tipos no copiables, Span y Embedded Swift tienen sentido sobre todo como respuesta a ese hueco.
Entonces, ¿es el Rust de Apple?
No en el sentido literal. Swift no va a exigir un verificador de préstamos con lifetimes en todo el código, ni busca sustituir a Rust en infraestructura multiplataforma. Lo que ocurre es más práctico: Swift está adquiriendo, de forma opcional, las piezas que permiten escribir código de sistemas con garantías similares, y lo hace sin romper la comodidad que lo hizo popular para apps. Para un desarrollador, la consecuencia es concreta:
- Para apps de iOS y macOS, el cambio importante sigue siendo la concurrencia: activar el modo de Swift 6 y entender el aislamiento.
- Para bibliotecas y código sensible al rendimiento, merece la pena aprender
~Copyable,borrowing,consumingySpan. - Para firmware o servidores en Swift, Embedded Swift y el SDK de Android abren opciones que no existían hace dos años.
- Para quien ya trabaja en Rust, la curva de entrada a estas funciones de Swift será suave: los conceptos son los mismos con otra sintaxis.
Swift y Rust convergen en las ideas, pero no compiten por el mismo desarrollador. Uno se queda en el terreno de las plataformas y aplicaciones, con una vía de escape hacia el bajo nivel; el otro parte del bajo nivel y tiene que subir hasta las aplicaciones. Esa convergencia, más que cualquier rivalidad, es lo que explica la pregunta del título.
Imagen: Pexels / Digital Buggu
