Что значит неизменное? - PullRequest
99 голосов
/ 08 июля 2010

Если строка неизменна, значит ли это, что .... (предположим, JavaScript)

var str = 'foo';

alert(str.substr(1)); // oo

alert(str); // foo

Означает ли это, что при вызове методов для строки она вернет измененную строку, но не изменит исходную строку?

Если строка была изменяемой, значит ли это, что 2-й alert() также вернет oo?

Ответы [ 8 ]

103 голосов
/ 08 июля 2010

Это означает, что как только вы создадите экземпляр объекта, вы не сможете изменить его свойства.В вашем первом предупреждении вы не меняете foo.Вы создаете новую строку.Вот почему в вашем втором предупреждении вместо «oo» будет отображаться «foo».

Означает ли это, что при вызове методов для строки она вернет измененную строку, но не изменится?исходная строка?

Да.Ничто не может изменить строку после ее создания.Теперь это не означает, что вы не можете назначить новый строковый объект переменной str.Вы просто не можете изменить текущий объект, на который ссылается str.

Если строка была изменяемой, значит ли это, что 2nd alert () также вернет oo?

Технически нет, потому что метод substring возвращает новую строку.Создание изменяемого объекта не изменит метод.Сделать его изменяемым означает, что технически вы можете сделать так, чтобы подстрока изменила исходную строку вместо создания новой.

93 голосов
/ 08 июля 2010

На более низком уровне неизменность означает, что память, в которой хранится строка, не будет изменена.Как только вы создаете строку "foo", часть памяти выделяется для хранения значения "foo".Эта память не будет изменена.Если вы измените строку, скажем, substr(1), будет создана новая строка и выделена другая часть памяти, в которой будет храниться "oo".Теперь у вас есть две строки в памяти, "foo" и "oo".Даже если вы больше не будете использовать "foo", он останется, пока не соберет мусор.

Одна из причин, почему строковые операции сравнительно дороги.

13 голосов
/ 08 июля 2010

Неизменяемый означает то, что не может быть изменено или модифицировано.

Таким образом, когда вы присваиваете значение строке, это значение создается с нуля, а не заменяется.Таким образом, каждый раз, когда новое значение присваивается той же строке, создается копия.Так что на самом деле вы никогда не меняете первоначальное значение.

9 голосов
/ 08 июля 2010

Я не уверен насчет JavaScript, но в Java строки делают дополнительный шаг к неизменности, используя «String Constant Pool».Строки могут быть созданы с помощью строковых литералов ("foo") или с помощью конструктора класса String.Строки, построенные из строковых литералов, являются частью пула строковых констант, и один и тот же строковый литерал всегда будет иметь тот же адрес памяти из пула.

Пример:

    String lit1 = "foo";
    String lit2 = "foo";
    String cons = new String("foo");

    System.out.println(lit1 == lit2);      // true
    System.out.println(lit1 == cons);      // false

    System.out.println(lit1.equals(cons)); // true

В приведенном вышеи lit1, и lit2 создаются с использованием одного строкового литерала, поэтому они указывают на один и тот же адрес памяти;lit1 == lit2 приводит к true, потому что это точно один и тот же объект.

Однако cons создается с использованием конструктора класса.Хотя параметр является той же строковой константой, конструктор выделяет новую память для cons, то есть cons не является тем же объектом, что и lit1 и lit2, несмотря на то, что он содержит те же данные.

OfКонечно, поскольку все три строки содержат одинаковые символьные данные, использование метода equals вернет true.

(Конечно, оба типа строковых конструкций являются неизменяемыми)

3 голосов
/ 16 февраля 2017

Определение изменчивости в учебнике может быть изменено или изменено. В программировании мы используем слово для обозначения объектов, состояние которых может изменяться со временем. Неизменное значение является полной противоположностью - после того, как оно было создано, оно никогда не сможет измениться.

Если это кажется странным, позвольте мне напомнить вам, что многие значения, которые мы используем все время, на самом деле неизменны.

var statement = "I am an immutable value";
var otherStr = statement.slice(8, 17);

Думаю, никто не удивится, узнав, что вторая строка никоим образом не меняет строку в выражении. Фактически, никакие строковые методы не изменяют строку, с которой они работают, все они возвращают новые строки. Причина в том, что строки неизменны - они не могут изменяться, мы можем только создавать новые строки.

Строки не единственные неизменные значения, встроенные в JavaScript. Числа тоже неизменны. Можете ли вы представить себе среду, в которой вычисление выражения 2 + 3 меняет значение числа 2? Это звучит абсурдно, но мы все время делаем это с нашими объектами и массивами.

3 голосов
/ 28 мая 2012

Неизменный означает, что значение не может быть изменено. После создания строковый объект не может быть изменен как его неизменный. Если вы запрашиваете подстроку строки, создается новая строка с запрошенной частью.

Использование StringBuffer при манипулировании строками вместо этого делает операцию более эффективной, поскольку StringBuffer сохраняет строку в массиве символов с переменными для хранения емкости массива символов и длины массива (строка в форме массива char)

2 голосов
/ 08 июля 2010

От строк до стеков ... простой для понимания пример, взятый из блога Эрика Липперта :

Поиск пути с использованием A * в C # 3.0, часть вторая ...

Изменчивый стек, такой как System.Collections.Generic.Stack, явно не подходит.Мы хотим иметь возможность взять существующий путь и создать из него новые пути для всех соседей его последнего элемента, но добавление нового узла в стандартный стек изменяет стек.Мы должны были бы сделать копии стека, прежде чем толкать его, что глупо, потому что тогда мы будем без необходимости дублировать все его содержимое.

Неизменяемые стеки не имеют этой проблемы.Вставка в неизменный стек просто создает совершенно новый стек, который связывается со старым как его хвост.Поскольку стек является неизменяемым, нет никакой опасности, что какой-то другой код может появиться и возиться с содержимым хвоста.Вы можете продолжать использовать старый стек, как душе угодно.

Чтобы углубиться в понимание неизменности, прочитайте посты Эрика, начиная с этого:

Неизменяемость в C # PartОдин: Виды Неизменности

0 голосов
/ 19 августа 2015

Один из способов понять эту концепцию - посмотреть, как javascript обрабатывает все объекты.Это означает, что все объекты являются изменяемыми после создания экземпляра, это означает, что вы можете добавить объект с новыми методами и свойствами.Это важно, потому что если вы хотите, чтобы объект был неизменным, он не может измениться после создания экземпляра.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...