tour taylor reputation premios joe edad canciones biografia alwyn swift pass-by-reference pass-by-value pass-by-pointer

taylor - ¿Swift pasa por valor o pasa por referencia?



taylor swift reputation tour (8)

Tipos de cosas en Swift

La regla es:

  • Las instancias de clase son tipos de referencia (es decir, su referencia a una instancia de clase es efectivamente un puntero )

  • Las funciones son tipos de referencia.

  • Todo lo demás es un tipo de valor ; "todo lo demás" simplemente significa instancias de estructuras e instancias de enumeraciones, porque eso es todo lo que hay en Swift. Las matrices y las cadenas son instancias de estructura, por ejemplo. Puede pasar una referencia a una de esas cosas (como argumento de función) usando inout y tomando la dirección, como ha señalado newacct. Pero el tipo es en sí mismo un tipo de valor.

Qué tipos de referencia significan para usted

Un objeto de tipo de referencia es especial en la práctica porque:

  • La mera asignación o pasar a la función puede generar múltiples referencias al mismo objeto

  • El objeto en sí es mutable incluso si la referencia a él es una constante (sea explícita o implícita).

  • Una mutación en el objeto afecta a ese objeto como lo ven todas las referencias a él.

Esos pueden ser peligros, así que esté atento. Por otro lado, pasar un tipo de referencia es claramente eficiente porque solo se copia y se pasa un puntero, lo cual es trivial.

¿Qué significan los tipos de valor para usted?

Claramente, pasar un tipo de valor es "más seguro", y let significa lo que dice: no puede mutar una instancia de estructura o una instancia de enumeración a través de una referencia de let . Por otro lado, esa seguridad se logra haciendo una copia separada del valor, ¿no es así? ¿No hace que pasar un tipo de valor sea potencialmente costoso?

Pues sí y no. No es tan malo como podrías pensar. Como dijo Nate Cook, pasar un tipo de valor no implica necesariamente copiar, porque let (explícito o implícito) garantiza la inmutabilidad, por lo que no hay necesidad de copiar nada. E incluso pasar a una referencia var no significa que las cosas se copiarán, solo que pueden serlo si es necesario (porque hay una mutación). Los documentos te aconsejan específicamente que no pongas tus bragas en un giro.

Soy realmente nuevo en Swift y acabo de leer que las clases se pasan por referencia y las matrices / cadenas, etc., se copian.

¿Es el pase por referencia de la misma manera que en Objective-C o Java en el que realmente pasa "una" referencia o es el pase correcto por referencia?


Aquí hay una pequeña muestra de código para pasar por referencia. Evite hacer esto, a menos que tenga una buena razón para hacerlo.

func ComputeSomeValues(_ value1: inout String, _ value2: inout Int){ value1 = "my great computation 1"; value2 = 123456; }

Llámalo así

var val1: String = ""; var val2: Int = -1; ComputeSomeValues(&val1, &val2);


Cuando se usa inout con un operador infijo como + =, entonces se puede ignorar el símbolo de dirección &. Supongo que el compilador supone pasar por referencia?

extension Dictionary { static func += (left: inout Dictionary, right: Dictionary) { for (key, value) in right { left[key] = value } } }

origDictionary + = newDictionaryToAdd

Y muy bien, este diccionario ''agregar'' solo escribe uno en la referencia original, ¡tan genial para bloquear!


El blog para desarrolladores de Apple Swift tiene una publicación llamada developer.apple.com/swift/blog/?id=10 que proporciona una discusión clara y detallada sobre este mismo tema.

Citar:

Los tipos en Swift se dividen en una de dos categorías: primero, "tipos de valor", donde cada instancia mantiene una copia única de sus datos, generalmente definida como una estructura, enumeración o tupla. El segundo, "tipos de referencia", donde las instancias comparten una sola copia de los datos, y el tipo generalmente se define como una clase.

La publicación de blog de Swift continúa explicando las diferencias con ejemplos y sugiere cuándo usaría uno sobre el otro.


Las clases se pasan por referencias y otras se pasan por valor en forma predeterminada. Puede pasar por referencia utilizando la palabra clave inout .


Todo en Swift se pasa por "copia" de forma predeterminada, por lo que cuando pasa un tipo de valor, obtiene una copia del valor, y cuando pasa un tipo de referencia, obtiene una copia de la referencia, con todo lo que eso implica. (Es decir, la copia de la referencia todavía apunta a la misma instancia que la referencia original).

Utilizo comillas de miedo alrededor de la "copia" anterior porque Swift hace mucha optimización; siempre que sea posible, no se copia hasta que haya una mutación o la posibilidad de mutación. Dado que los parámetros son inmutables de manera predeterminada, esto significa que la mayoría de las veces no se produce ninguna copia.


Siempre es paso por valor cuando el parámetro no está inout .

Siempre es paso por referencia si el parámetro está inout . Sin embargo, esto es algo complicado por el hecho de que necesita usar explícitamente el operador & en el argumento al pasar a un parámetro inout , por lo que puede no ajustarse a la definición tradicional de paso por referencia, donde pasa la variable directamente.


Clases y estructuras

Una de las diferencias más importantes entre estructuras y clases es que las estructuras siempre se copian cuando se pasan en su código, pero las clases se pasan por referencia.

Cierres

Si asigna un cierre a una propiedad de una instancia de clase, y el cierre captura esa instancia al referirse a la instancia o sus miembros, creará un ciclo de referencia fuerte entre el cierre y la instancia. Swift usa listas de captura para romper estos fuertes ciclos de referencia

ARC (conteo automático de referencia)

El recuento de referencias solo se aplica a instancias de clases. Las estructuras y las enumeraciones son tipos de valor, no tipos de referencia, y no se almacenan ni se pasan por referencia.