//Parámetros tipo inoutfunc swapTwoInts(_ a: inout Int,_ b: inout Int){let tempA = a
a = b
b = tempA
}var someInt =3var otherInt =7print("someInt var \(someInt) y otherInt vale \(otherInt)")swapTwoInts(&someInt,&otherInt)print("someInt var \(someInt) y otherInt vale \(otherInt)")
No se en que ámbito se puede usar inout.. Creo que es una mala práctica y algo bastante peligroso..
Cuando estás programando estructuras de control como pueden ser listas enlazadas, colas, pilas, etc. (OJO! Que no diga usarlas digo programarlas) tendrás funciones útiles en las que NECESARIAMENTE tendrás que pasar la referencia de un nodo, por ejemplo.
Viene de C donde las variables claramente tienen valor y referencia indicados con el * y &
Hay ocasiones en las que son útiles y otras en las que es necesario este tipo de funcionalidades.
Por ejemplo si vienes de mundo JS (como yo) no lo ves porque técnicamente nunca necesitas ese tipo de características.
Es practico tener funciones de ayuda que puedan ser re utilizadas en todo el proyecto. Pero concuerdo con que puede llegar a ser un dolor de cabeza si son mal utilizadas. La ventaja que le veo, tal vez, es el ahorro de memoria, ya que no estas creando nuevas variables, sino utilizando al referencia de memoria de las ya existentes.
let x =5funcaddOne(number:Int){// number += 1print("El numero ahora vale \(number)")}addOne(number: x)
La operación number += 1 no se puede realizar porque los parámetros de una función son de solo lectura (constantes).
El error que veremos es:
Left side of mutating operator isn't mutable: 'number' is a 'let' constant.
Para resolver este problema se utiliza la palabra reservada inout en la definición de cada parámetro:
funcswapTwoInts(_ a:inoutInt,_ b:inoutInt){let tempA = a
a = b
b = tempA
}var someInt =3var otherInt =7print("someInt vale \(someInt) y otherInt vale \(otherInt)")
Ahora, para pasar los parámetros a la función, tenemos que utilizar el operador & para indicar que estamos pasando una referencia (dirección de memoria) de la variable y no una copia del mismo.
swapTwoInts(a: &Int, b: &Int)
swapTwoInts(&someInt,&otherInt)print("someInt vale \(someInt) y otherInt vale \(otherInt)")// outputs:someInt vale 3 y otherInt vale 7someInt vale 7 y otherInt vale 3
Esto guarda mucha relación con punteros y operadores de indirección 🤠
seguro tiene su aplicación muy particular pero cuando empiezas a manipular referencias en lugar de pasar mensajes entre objetos se puede llegar a estados de inconsistencia difíciles de mantener.
// para poder alterar los valores de los parámetros se usa: inout// y luego, al llamar la función se usa '&'func swapTwoInts(_ a: inout Int, _ b: inout Int){let tempA = a
a = b
b = tempA
}var someInt =3var otherInt =7print("SomeInt vale \(someInt) y otherInt vale \(otherInt)")swapTwoInts(&someInt,&otherInt)print("SomeInt vale \(someInt) y otherInt vale \(otherInt)")
Inout y Inout sustituyen el return?
esto es como los punteros
Creo que puede ser utilizado para funciones reactivas que usan mucho en aplicaciones web dinámicas.
Creo que así queda claro lo que pasa con una función inout
Me sorprendió que el profesor dijera que es un tema complicado porque me quedo super claro, al contrario me reventó la cabeza fue algo como wow 🤯🤯
Excelente profesor!
Por si alguno se pregunta como seria con el ejemplo anterior:
var x =5func addOne(number: inout Int){ number +=1}addOne(number:&x)print("El numero ahora vale \(x)")
puede ser una funcion de doble filo 🤔
Gracias por tan buena explicación, me quedo claro! 👍