Empieza por struct para un modelo que representa un valor y elige class cuando necesitas identidad o estado de objeto compartido. Envolver un objeto en un struct no lo independiza ni lo hace seguro entre hilos.
Mecanismo y decisión de diseño
Asignar un struct copia sus valores almacenados. Si una propiedad contiene una referencia de clase, se copia la referencia y se comparte el objeto. Distingue esto de la copia profunda y la seguridad entre hilos. La herencia y las API de objetos Objective-C también influyen. Fuente primaria
Código reproducible
El experimento copia el entero de Point, una referencia Box y un Envelope que contiene un Box. Distingue entre cambiar una propiedad del objeto y sustituir el box de la copia por otro objeto. Las precondiciones verifican ambos valores en cada paso.
Este ejemplo independiente se ejecutó el 2026-10-23 con Apple Swift 6.4 para arm64 macOS, en modo de lenguaje Swift 6. No necesita red ni paquetes adicionales.
Descargar el archivo Swift completo
Ejecuta el comando en la carpeta de descarga. Las precondiciones detienen la ejecución si falla una comprobación. No uses -Ounchecked: elimina estas comprobaciones.
swift -swift-version 6 swift-class-vs-struct.swift
struct Point { var x: Int }
final class Box {
var x: Int
init(_ x: Int) { self.x = x }
}
struct Envelope { var box: Box }
let point = Point(x: 0)
var copiedPoint = point
copiedPoint.x = 10
precondition(point.x == 0 && copiedPoint.x == 10)
let box = Box(0)
let copiedReference = box
copiedReference.x = 10
precondition(box === copiedReference && box.x == 10)
let envelope = Envelope(box: Box(0))
var copiedEnvelope = envelope
copiedEnvelope.box.x = 20
precondition(envelope.box.x == 20)
copiedEnvelope.box = Box(30)
precondition(envelope.box.x == 20 && copiedEnvelope.box.x == 30)
print("struct=0,10 class=10,10 nested-reference=20,20 replacement=20,30")
Salida registrada e interpretación
struct=0,10 class=10,10 nested-reference=20,20 replacement=20,30
Point pasa a tener 0 y 10; las referencias Box comparten 10. Modificar el objeto mediante la copia de Envelope hace que ambos observen 20. Sustituir su box por Box(30) deja el original en 20. Independencia de propiedades e identidad compartida son cosas distintas.
Alcance y limitaciones
Este experimento secuencial comprueba semántica de copia, no carreras ni rendimiento. Compartir una variable mutable o una referencia interna todavía exige aislamiento o sincronización. La comprobación Sendable de Swift 6 no equivale a declarar struct.
Qué comprobar después
Enumera qué estado debe cambiar conjuntamente tras copiar el modelo. Si compartir referencias no es intencional, considera valores inmutables o una política explícita de clonación. Para copiar almacenamiento grande eficientemente, sigue con el experimento CoW.
Fuentes y verificación
- The Swift Programming Language: Structures and ClassesSwift.org · Documentación oficial · Consultado 23 de octubre de 2026Respalda: Fuente del contrato de implementación y de la explicación. La salida se comprobó por separado con el experimento incluido aquí.

