Неглубокое копирование в MATLAB

Многие люди сталкиваются с неожиданным поведением мелкого копирования, когда начинают работать с Python, и я хотел бы убедиться, что не совершу ни одной из этих ошибок в MATLAB (с которым у меня меньше опыта).

Я прочитал эту статью о поведении объектов в MATLAB и Я прочитал этот вопрос это относится к поведению указателя/дескриптора. Существуют ли ситуации, когда isa(obj, 'handle') вернет false, но вы все равно столкнетесь с ситуацией, когда изменение obj приведет к изменению другой переменной (насколько мне известно, любое изменение аргумента вызовом функции должно вызывать копировать при записи и дублировать переменную в памяти)?

Является ли это полным пониманием поведения, подобного «поверхностному копированию» в MATLAB? Существуют ли какие-либо дополнительные предостережения относительно поведения при копировании объекта со стандартным значением?


person Peter Barrett Bryan    schedule 18.01.2018    source источник


Ответы (1)


Класс значения может содержать класс дескриптора, и если вы измените его, вы измените экземпляр класса дескриптора. Например (обратите внимание, что containers.Map — это встроенный класс, который является дескриптором — ничего особенного в этом нет, я просто выбрал его для удобства:

>> a = containers.Map; a('hello') = 1;
>> b = struct('field1', 1, 'field2', a);
>> isa(b, 'handle')
ans =
  logical
   0
>> b.field2('hello') = 2;
>> a('hello')
ans =
     2

Итак, b — это структура (которая имеет семантику значений), но одно из ее полей содержит containers.Map, который является дескриптором и имеет ссылочную семантику. Когда вы изменяете это поле, вы также изменяете a, который является еще одной ссылкой на основной containers.Map.

person Sam Roberts    schedule 18.01.2018
comment
Отличный ответ. Я вообще не рассматривал этот пограничный случай. Я очень ценю демонстрацию кода конкретных заданных вопросов - person Peter Barrett Bryan; 18.01.2018
comment
Рад, что мой ответ помог. Хотя на самом деле это не крайний случай - это пример более общей проблемы. b не обязательно должна быть структурой — это может быть массив ячеек с a в качестве элемента или экземпляр класса значений с a в качестве свойства. Это мог быть дескриптор функции, захвативший a в своей рабочей области, и так далее. А a мог быть скрыт на несколько уровней глубже внутри b. - person Sam Roberts; 18.01.2018
comment
Хотя в этом случае isa(b.field2, 'handle') возвращает true. Так что вы всегда можете заранее знать, что это произойдет. - person Cris Luengo; 18.01.2018
comment
@CrisLuengo Это верно в случае, когда b является структурой, а дескриптор хранится как поле, но это не всегда возможно - например, если дескриптор был сохранен в частном свойстве класса значений b. Дескриптор может быть изменен методом b, что приведет к изменению других ссылок на него, но у вас не будет доступа к дескриптору, чтобы проверить его так, как вы описываете. - person Sam Roberts; 19.01.2018
comment
@SamRoberts: Хм, интересно. И удивительно. Думаю, вы правы. - person Cris Luengo; 19.01.2018