¿Qué significa un ampersand (&) en el lenguaje Swift?

Sé sobre el signo y como operación de bit, pero a veces lo veo frente a nombres variables. ¿Qué significa poner un & delante de las variables?

Funciona como una inout para hacer que la variable sea un parámetro de entrada y salida. In-out significa, de hecho, pasar el valor por referencia, no por valor. Y requiere no solo aceptar el valor por referencia, sino también pasarlo por referencia, así que foo(&myVar) con & – foo(&myVar) lugar de solo foo(myVar)

Como puede ver, puede usar eso al entregar Swift en error, donde debe crear una referencia de error y pasarla a la función usando & la función rellenará el valor de error si ocurre un error o devolverá la variable como antes.

¿Por qué lo usamos? A veces, una función ya devuelve otros valores y simplemente devolver otra (como un error) sería confuso, por lo que lo pasamos como inout. En otras ocasiones, queremos que los valores sean completados por la función para que no tengamos que iterar sobre muchos valores devueltos, ya que la función ya lo hizo por nosotros, entre otros usos posibles.

¡Espero que eso te ayude!

Significa que es una variable de entrada y salida. Puedes hacer algo directamente con esa variable. Se pasa por una dirección, no como una copia.

Por ejemplo:

 var temp = 10 func add(inout a: Int){ a++ } add(&temp) temp // 11 

Si pones & antes de una variable en una función, eso significa que esta variable está fuera de la variable.

@Icaro ya describió lo que significa, daré un ejemplo para ilustrar la diferencia entre las variables inout y las variables:

 func majec(inout xValue:Int, var yValue:Int) { xValue = 100 yValue = 200 } var xValue = 33 var yValue = 33 majec(&xValue, yValue: yValue) xValue //100 yValue //33 

Como se indicó en otras respuestas, usa el prefijo & para pasar un valor a un parámetro inout de un método o llamada de función, como se documenta en Funciones> Etiquetas de argumento de función y nombres de parámetros> Parámetros de entrada / salida en El lenguaje de progtwigción Swift . Pero hay más que eso.

En la práctica, puede pensar en Swift inout parameters y pasarle valores como similares a C o C ++ pass-by-address o pass-by-reference. De hecho, el comstackdor optimizará muchos usos de los parámetros inout hasta más o menos los mismos mecanismos (especialmente cuando llama a C u ObjC API importadas que tratan con punteros). Sin embargo, esas son solo optimizaciones: en un nivel semántico, realmente no pasa las direcciones, lo que libera al comstackdor para hacer que este lenguaje sea más flexible y poderoso.

Por ejemplo, aquí hay una estructura que usa una estrategia común para validar el acceso a una de sus propiedades:

 struct Point { private var _x: Int var x: Int { get { print("get x: \(_x)") return _x } set { print("set x: \(newValue)") _x = newValue } } // ... same for y ... init(x: Int, y: Int) { self._x = x; self._y = y } } 

(En código “real”, getter y setter para x podrían hacer cosas como forzar valores mínimos / máximos. Ox podría hacer otros trucos de propiedades computadas, como hablar con una base de datos SQL bajo el capó. Aquí simplemente instrumentamos la llamada y obtener / establecer la propiedad privada subyacente).

Ahora, ¿qué sucede cuando pasamos x a un parámetro inout ?

 func plusOne(num: inout Int) { num += 1 } var pt = Point(x: 0, y: 1) plusOne(num: &pt.x) // prints: // get x: 0 // set x: 1 

Entonces, aunque x es una propiedad calculada, pasarla “por referencia” usando un parámetro inout funciona igual que lo esperado si x fuera una propiedad almacenada o una variable local.


Esto significa que puede pasar todo tipo de cosas “por referencia” que ni siquiera podría considerar en C / C ++ / ObjC. Por ejemplo, considere la función de swap biblioteca estándar, que toma dos “cosas” y cambia sus valores:

 var a = 1, b = 2 swap(&a, &b) print(a, b) // -> 2 1 var dict = [ "Malcolm": "Captain", "Kaylee": "Mechanic" ] swap(&dict["Malcolm"], &dict["Kaylee"]) print(dict) // -> ["Kaylee": "Captain", "Malcolm": "Mechanic"], fanfic ahoy let window1 = NSWindow() let window2 = NSWindow() window1.title = "window 1" window2.title = "window 2" var windows = [window1, window2] swap(&windows[0], &windows[1]) print(windows.map { $0.title }) // -> ["window 2", "window 1"] 

La forma en que inout funciona también le permite hacer cosas divertidas como usar el operador += en cadenas de llamadas anidadas:

 window.frame.origin.x += 10 

… que es mucho más simple que descomponer un CGRect solo para construir uno nuevo con una coordenada x diferente.


Esta versión más matizada del comportamiento inout , llamada “resultado de llamada por valor”, y las formas en que se puede optimizar hasta el comportamiento de “paso por dirección” estilo C, se trata en Declaraciones> Funciones> Parámetros de entrada y salida en Progtwigción Swift Idioma .

    Intereting Posts