Erste Anmerkung: Ich arbeite in Julia, aber diese Frage gilt wahrscheinlich für viele Sprachen.Verstehende unveränderliche zusammengesetzte Typen mit Feldern von veränderbaren Typen in Julia
Setup: Ich habe einen zusammengesetzten Typ wie folgt:
type MyType
x::Vector{String}
end
Ich schreibe einige Methoden auf MyType
zu handeln. Zum Beispiel schreibe ich eine Methode, die es mir erlaubt, ein neues Element in x
, z. function insert!(d::MyType, itemToInsert::String)
.
Frage: Sollte MyType
veränderlich oder unveränderlich sein?
Mein Verständnis: ich die Julia docs auf diesem gelesen habe, sowie allgemeinere (und sehr upvoted) Fragen auf Stackoverflow (zB here oder here), aber ich habe immer noch nicht wirklich einen guten Griff auf was es bedeutet, wandelbar/unveränderlich aus praktischer Sicht zu sein
Dennoch, hier ist mein Versuch (vor allem für den Fall eines unveränderlichen zusammengesetzten Typs, einen änderbaren Array von unveränderlichen Typen enthalten!): Wenn MyType
unveränderlich ist, dann bedeutet das, dass das Feld x
immer auf das gleiche Objekt zeigen muss. Dieses Objekt selbst (ein Vektor von Strings) ist veränderbar, also ist es völlig in Ordnung, neue Elemente darin einzufügen. Was ich nicht tun darf, ist zu versuchen und zu ändern MyType
, so dass das Feld x
auf ein ganz anderes Objekt zeigt. Zum Beispiel sind Verfahren, die die folgenden sind in Ordnung zu tun:
MyType.x[1] = "NewValue"
push!(MyType.x, "NewElementToAdd")
Aber Methoden, die die folgenden sind nicht in Ordnung zu tun:
MyType.x = ["a", "different", "string", "array"]
Ist das richtig? Ist auch die Idee, dass das Objekt, mit dem ein unveränderlicher Typenfeld-Werte gesperrt sind, diejenigen sind, die innerhalb des Konstruktors erstellt werden?
Endgültiger Punkt: Ich entschuldige mich, wenn dies scheint, andere Fragen zu SO zu duplizieren. Wie gesagt, ich habe sie durchgesehen und konnte nicht verstehen, was ich suchte.
Während Julian Arrays nicht in Julia selbst implementiert sind, denke ich, dass ein Array mehrere Felder hat (für die Dimensionalität und den Zeiger auf den Speicher, in dem sich die Daten befinden). 'pointer (x.data)' zeigt an, wo dieses Speicherfeld zeigt ... und dass es * sich innerhalb * des Vektorobjekts ändert. Aber wiederholen Sie Ihr Experiment, diesmal mit ['pointer_from_objref (x.data)'] (http://docs.julaulang.org/en/latest/stdlib/base/?highlight=pointer_from_objref#Base.pointer_from_objref), um die Adresse anzuzeigen des Vector-Objekts selbst. –
Siehe [julia.h: 88-120] (https://github.com/JuliaLang/julia/blob/master/src/julia.h#L88-L120) für die Anordnung der Array-Objekte im Speicher als Nackte C-Struktur. –
Ah, das macht mehr Sinn – IainDunning