Crear copias en Julia con = operador

Cuando creo una matriz A y la asigno a B

A = [1:10] B = A 

Puedo modificar A y el cambio se refleja en B

 A[1] = 42 # B[1] is now 42 

Pero si hago eso con variables escalares, el cambio no se propaga:

 a = 1 b = a a = 2 # b remains being 1 

Incluso puedo mezclar las cosas y transformar el vector a escalar, y el cambio no se propaga:

 A = [1:10] B = A A = 0 # B remains being 1,2,...,10 

¿Qué hace exactamente el operador = ? Cuando quiero copiar variables y modificar las antiguas conservando la integridad de las nuevas variables, ¿cuándo debería usar b = copy(a) solo sobre b=a ?

La confusión surge de esto: la asignación y la mutación no son lo mismo.

Asignación. La asignación se ve como x = ... – lo que queda de = es un identificador, es decir, un nombre de variable. La asignación cambia a qué objeto se refiere la variable x (esto se denomina vinculación variable). No muta ningún objeto en absoluto.

Mutación. Hay dos formas típicas de mutar algo en Julia: xf = ... – lo que queda de = es una expresión de acceso de campo; x[i] = ... – lo que queda de = es una expresión de indexación. Actualmente, la mutación de campo es fundamental: esa syntax solo puede significar que estás mutando una estructura cambiando su campo. Esto puede cambiar La syntax de la mutación del array no es fundamental: x[i] = y significa setindex!(x, y, i) y puede agregar métodos al setindex. o cambiar localmente qué función genérica setindex! . La asignación real de la matriz es una función incorporada, implementada en C (y para la cual sabemos cómo generar el código LLVM correspondiente).

La mutación cambia los valores de los objetos; no cambia ningún enlace de variable. Después de hacer cualquiera de las anteriores, la variable x todavía se refiere al mismo objeto que antes; ese objeto puede tener diferentes contenidos, sin embargo. En particular, si se puede acceder a ese objeto desde otro ámbito, digamos la función que llamó a uno haciendo la mutación, entonces el valor modificado será visible allí. Pero ninguna vinculación ha cambiado: todas las vinculaciones en todos los ámbitos todavía se refieren a los mismos objetos.

Notarás que en esta explicación nunca hablé sobre mutabilidad o inmutabilidad. Esto se debe a que no tiene nada que ver con nada de esto: los objetos mutables e inmutables tienen exactamente la misma semántica en lo que respecta a la asignación, el paso de argumentos, etc. La única diferencia es que si intentas hacer xf = ... cuando x es inmutable, obtendrá un error.

Este comportamiento es similar a Java. A y B son variables que pueden contener un tipo de datos “simple”, como un entero, flotante, etc., o una referencia (también conocida como punteros) a una estructura de datos más compleja. A diferencia de Java, Julia maneja muchos tipos no abstractos como datos “simples”.

Puede probar con isbits(A) si su variable A contiene un valor de bit o contiene una referencia a otro objeto de datos. En el primer caso B=A copiará cada bit de A a una nueva asignación de memoria para B ; de lo contrario, solo se copiará la referencia al objeto.

Juega también con pointer_from_objref(A) .

    Intereting Posts