Начальное примечание: Я работаю в Джулии, но этот вопрос, вероятно, относится ко многим языкам.Понимание неизменяемых композитных типов с полями изменяемых типов в Julia
Установка: У меня есть композитный тип следующим образом:
type MyType
x::Vector{String}
end
Я пишу некоторые методы действуют на MyType
. Например, я пишу метод, который позволяет мне вставить новый элемент в x
, например. function insert!(d::MyType, itemToInsert::String)
.
Вопрос: Должно ли MyType
быть изменчивым или неизменным?
Мое понимание: Я прочитал Julia docs на этом, а также более общие (и весьма upvoted) вопросы по Stackoverflow (например here или here), но я до сих пор на самом деле не имеют хорошую ручку что значит быть изменяемыми/неизменны с практической точки зрения
Тем не менее, вот моя попытка (особенно для случая неизменного составного типа, содержащего изменяемый массив неизменяемых типов!): Если MyType
неизменен, то это означает, что поле x
должно всегда указывать на один и тот же объект. Сам этот объект (вектор строк) изменен, поэтому для меня совершенно нормально вставлять в него новые элементы. То, что мне не разрешено, это попробовать и изменить MyType
так, чтобы поле x
указывало на совершенно другой объект. Например, методы, которые делают следующее в порядке:
MyType.x[1] = "NewValue"
push!(MyType.x, "NewElementToAdd")
Но методы, которые делают следующее не в порядке:
MyType.x = ["a", "different", "string", "array"]
Правильно ли это? Кроме того, является ли идея, что объект, к которому привязаны значения неизменяемых типов полей, относится к тем, которые создаются внутри конструктора?
Конечная точка: Приносим извинения, если это похоже на дублирование других вопросов. Как было сказано, я просмотрел их и не смог понять, что мне нужно.
Хотя юлианские массивы не реализованы в самой Джулии, я думаю, что массив имеет несколько полей (для размерности и указателя на память, в которой находятся данные). 'pointer (x.data)' показывает, где это поле памяти указывает ... и что он меняет * внутри * векторного объекта. Но повторите свой эксперимент, на этот раз с помощью ['pointer_from_objref (x.data)'] (http://docs.julialang.org/en/latest/stdlib/base/?highlight=pointer_from_objref#Base.pointer_from_objref), чтобы показать адрес самого объекта Vector. –
См. [Julia.h: 88-120] (https://github.com/JuliaLang/julia/blob/master/src/julia.h#L88-L120) о том, как объекты массива выкладываются в памяти как голова C struct. –
Ах, что имеет смысл – IainDunning