una referencia punteros por paso pasar parametros parametro funciones funcion con como bidimensional arreglo array arrays swift pass-by-reference

arrays - referencia - paso arreglo de funciones



Swift: ¿pasar matriz por referencia? (8)

Algo como

var a : Int[] = [] func test(inout b : Int[]) { b += [1,2,3,4,5] } test(&a) println(a)

???

Quiero pasar mi Swift Array chatsViewController.chats a chatsViewController.chats por referencia (para que cuando agregue un chat a chatsViewController.chats , chatsViewController.chats siga chatsViewController.chats ). Es decir, no quiero que Swift separe las dos matrices cuando cambie la longitud de account.chats .


Defina usted mismo un BoxedArray<T> que implemente la interfaz Array pero delegue todas las funciones en una propiedad almacenada. Como tal

class BoxedArray<T> : MutableCollection, Reflectable, ... { var array : Array<T> // ... subscript (index: Int) -> T { get { return array[index] } set(newValue) { array[index] = newValue } } }

Usa el BoxedArray cualquier lugar donde uses una Array . La asignación de un BoxedArray será por referencia, es una clase, y por lo tanto los cambios a la propiedad almacenada, a través de la interfaz Array , serán visibles para todas las referencias.


Las estructuras en Swift se pasan por valor, pero puedes usar el modificador inout para modificar tu matriz (ver respuestas a continuación). Las clases se pasan por referencia. Array y Dictionary in Swift se implementan como estructuras.


Otra opción es hacer que el consumidor de la matriz pregunte al propietario si es necesario. Por ejemplo, algo como:

class Account { var chats : [String]! var chatsViewController : ChatsViewController! func InitViewController() { chatsViewController.getChats = { return self.chats } } } class ChatsViewController { var getChats: (() -> ([String]))! func doSomethingWithChats() { let chats = getChats() // use it as needed } }

A continuación, puede modificar la matriz tanto como desee dentro de la clase Cuenta. Tenga en cuenta que esto no lo ayudará si también desea modificar la matriz de la clase de controlador de vista.


Para el operador del parámetro de función usamos:

let (es el operador predeterminado, por lo que podemos omitir let ) para hacer un parámetro constante (significa que no podemos modificar incluso la copia local);

var para hacerlo variable (podemos modificarlo localmente, pero no afectará a la variable externa que se ha pasado a la función); y

inout para convertirlo en un parámetro in-out. In-out significa, de hecho, pasar variable 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)

Entonces hazlo así:

var arr = [1, 2, 3] func addItem(inout localArr: [Int]) { localArr.append(4) } addItem(&arr) println(arr) // it will print [1, 2, 3, 4]

Para ser exactos, no es solo una referencia, sino un alias real para la variable externa, por lo que puede hacer ese truco con cualquier tipo de variable, por ejemplo, con entero (puede asignarle un nuevo valor), aunque puede que no sea un buenas prácticas y puede ser confuso modificar los tipos de datos primitivos como este.


Para las versiones 3-4 de Swift (XCode 8-9), use

var arr = [1, 2, 3] func addItem(_ localArr: inout [Int]) { localArr.append(4) } addItem(&arr) print(arr)


Swift 3 y Xcode 8:

var myArray = [1, 2, 3] for (index, value) in myArray.enumerated() { // if you don''t need the value you could do: for (index, _) in myArray.enumerated() myArray[index].append(4) }


Usar inout es una solución, pero no me parece muy fácil porque las matrices son tipos de valores. Estilísticamente, personalmente prefiero devolver una copia mutada:

func doSomething(to arr: [Int]) -> [Int] { var arr = arr arr.append(3) // or likely some more complex operation return arr } var ids = [1, 2] ids = doSomething(to: ids) print(ids) // [1,2,3]