El siguiente código compila y funciona en Swift.
struct TestStruct { let value: String = "asdf" } func iWantAReferenceType(object: AnyObject) { print(String(describing: object)) } let o: TestStruct = TestStruct() iWantAReferenceType(object: o as AnyObject)Esperaba que esto fuera un error de compilación porque una estructura nunca puede ajustarse a AnyObject. Como se demuestra a continuación por el código que no se puede compilar.
protocol Test: AnyObject { } //Compile error: because a struct cannot be AnyObject struct TestStruct: Test { let value: String = "asdf" }Soy consciente de que pueden producirse algunos puentes para ciertos tipos, como String. Esto convertiría el tipo de valor de un tipo de referencia.
print(Mirror(reflecting: "asdf").subjectType) //print: String print(Mirror(reflecting: "asdf" as AnyObject).subjectType) //print: NSTaggedPointerStringAl escribir esta pregunta, pensé en ver cuál era el tipo de objeto emitido y parece que también está conectado de alguna manera.
print(Mirror(reflecting: o).subjectType) //prints: TestStruct print(Mirror(reflecting: o as AnyObject).subjectType) //prints: _SwiftValue¿Por qué se permite este tipo de casting? Parece estar rompiendo el contrato de la función que espera un tipo de referencia.
Me topé con esto por accidente al refactorizar un código para admitir tipos de valor, para mi sorpresa, ya había estado funcionando para tipos de valor aunque pensé que no lo haría. ¿Es seguro confiar en este comportamiento?
Esta es una función para facilitar el paso a Cocoa. Cualquier estructura se puede envolver en un tipo de referencia SwiftValue . Si imprime el type(of: object) , verá el envoltorio.
No creo que haya ningún contrato para "esperar un tipo de referencia". Más importante aún, si bien existen "tipos de valor" y "tipos de referencia" en Swift, lo que realmente importa es la semántica de valor y referencia, que no se puede expresar en el lenguaje. Puede crear semántica de valor en tipos de referencia y semántica de referencia en tipos de valor, por lo que el sistema de tipo Swift realmente no es de ninguna ayuda en ese sentido.
El punto importante aquí es que solo obtiene este comportamiento inusual si lo solicita explícitamente as AnyObject . Hay muy pocas razones para escribir eso, y si es así, es mejor que sepa exactamente lo que está haciendo.