2015-10-07 14 views
13

Quando creo alcune serie A e assegnarlo a BCreazione di copie a Julia con operatore =

A = [1:10] 
B = A 

posso modificare A e la variazione riflette in B

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

Ma se lo faccio con variabili scalari, il cambiamento non si propaga:

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

posso anche mescolare le cose e trasformare il vettore a una scala R, e il cambiamento non propaga:

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

Che cosa fa esattamente l'operatore = fa? Quando voglio copiare le variabili e modificare quelle vecchie preservando l'integrità delle nuove variabili, quando dovrei usare b = copy(a) su solo b=a?

+0

Sulla base della vostra anticipazione dei risultati riflessi dalla domanda, il linguaggio R può darvi meno sorpresa. – colinfang

risposta

24

La confusione deriva da questo: assegnazione e mutazione non sono la stessa cosa.

Assegnazione. L'assegnazione è simile a x = ... - ciò che resta dello = è un identificativo, ovvero un nome di variabile. Modifiche di assegnazione che obietta la variabile x si riferisce a (questo è chiamato un legame variabile). Non muta affatto alcun oggetto.

Mutazione. Esistono due modi tipici per mutare qualcosa in Julia: x.f = ... - ciò che resta dello = è un'espressione di accesso al campo; x[i] = ... - ciò che resta dello = è un'espressione di indicizzazione. Attualmente, la mutazione del campo è fondamentale: la sintassi può solo significa che si sta modificando una struttura modificando il suo campo. Questo potrebbe cambiare. La sintassi della mutazione delle matrici non è fondamentale - x[i] = y significa setindex!(x, y, i) e puoi aggiungere metodi a setindex! o cambiare localmente quale funzione generica setindex!. L'effettiva assegnazione dell'array è un builtin - una funzione implementata in C (e per la quale sappiamo come generare il corrispondente codice LLVM).

La mutazione modifica i valori degli oggetti; non cambia alcuna associazione di variabili. Dopo aver eseguito una di queste operazioni, la variabile x si riferisce ancora allo stesso oggetto che ha fatto prima; quell'oggetto può avere contenuti diversi, comunque. In particolare, se quell'oggetto è accessibile da qualche altro ambito - ad esempio la funzione che ha chiamato uno facendo la mutazione - allora il valore modificato sarà visibile lì. Ma nessun legame è cambiato - tutti i collegamenti in tutti gli ambiti si riferiscono ancora agli stessi oggetti.

Noterete che in questa spiegazione non ho mai parlato di mutabilità o immutabilità. Questo perché non ha nulla a che fare con questo: gli oggetti mutabili e immutabili hanno esattamente la stessa semantica quando si tratta di assegnare, passare argomenti, ecc. L'unica differenza è che se si prova a fare x.f = ... quando x è immutabile, si ricevi un errore

+0

Grazie per la risposta completa. Come ho capito, tutte le mie operazioni 'b = a' sono assegnazioni, quindi in tutti i casi' b' dovrebbe fare riferimento a 'a'. Cosa mi manca? – RedPointyJackson

+0

Quando fai 'A [1] = 42' è una mutazione, non un compito. – StefanKarpinski

+0

Ok, l'ho capito. Ma quando eseguo 'b = a', dovrebbe essere assegnato perché è un'operazione nello stile' x = ... ', giusto? Così ora ho 'b' 'indicato' a' a', e tutte le modifiche in 'a' dovrebbero riflettere ogni volta che valuto b, vero? – RedPointyJackson

-4

Questo comportamento è simile a Java. A e B sono variabili che possono contenere sia un tipo di dati "semplice", come un intero, un float ecc., Sia riferimenti (anche detti puntatori) a una struttura dati più complessa. A differenza di Java, Julia gestisce molti tipi non astratti come dati "semplici".

È possibile verificare con isbits(A) se la variabile A contiene un valore di bit o contiene un riferimento a un altro oggetto di dati. Nel primo caso, B=A copierà ogni bit da A a una nuova allocazione di memoria per B, altrimenti verrà copiato solo il riferimento all'oggetto.

Gioca anche con pointer_from_objref(A).

+2

Questa risposta è fuorviante al meglio: la mutabilità rispetto all'immutabilità è una falsa pista. I valori mutabili e immutabili hanno una semantica identica in entrambe le lingue - entrambi hanno una semantica di riferimento. Questo perché né Julia né Java hanno tipi di valori mutabili, come le strutture di C, che hanno una semantica osservabile in modo differente. – StefanKarpinski