2010-07-08 2 views
92

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

var str = 'foo'; 

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

alert(str); // foo 

Означает ли это, при вызове методов на строку, он возвращает модифицированную строку, но он выиграл 'изменить исходную строку?

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

ответ

100

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

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

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

Если строка была изменчивой, значит ли это означает, что второе предупреждение() возвращает оо , а?

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

+0

Эта же строка, если она изменена и назначена, обновит строку var str = 'foo'; str = str.substr (1)); // oo alert (str); // oo –

+0

Как насчет ниже кода. Строковое значение теперь изменяется. var name = "Santosh"; console.log (name.substr (0,2)); var name = "kumar" console.log (имя); Как его все еще неизменен – Santosh

12

Неизменяемый означает то, что нельзя изменить или изменить.

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

2

Из строк в штабеля ... просто понять пример, взятый из Eric Lippert's blog:

Path Finding Using A* in C# 3.0, Part Two ...

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

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

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

Immutability in C# Part One: Kinds of Immutability

+0

Эта цитата содержит нечетное утверждение: структура данных стека (на самом деле несколько стеков с совместным использованием хвоста) является, в целом, изменяемой структурой - каждый push или pop изменяет структуру. Только отдельные элементы неизменяемы. И в принципе, вы могли бы иметь ту же структуру, но с изменяемыми элементами. Это происходит в некоторых вариантах отмены Unix-find IIRC. Невосстановимость имеет большие преимущества, но разделение части или всей структуры данных в качестве оптимизации вполне возможно с помощью переменных. Даже если вам нужна очевидная неизменность для других ссылок, вы всегда можете копировать по мере необходимости. – Steve314

86

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

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

+5

+1 спасибо, это полезно знать – alex

+1

Номера неизменяемы. –

+3

привет от 2015 !! «На более низком уровне неизменность означает, что память, в которой хранится строка, не будет изменена». --- Это слишком ограничительно и не звучит правильно. Неизменяемость - это только пользовательская область, виртуальная память может быть изменена по мере того, как распределяется распределитель памяти, как только сохраняются языковые инварианты. – zerkms

8

Я не уверен в 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, несмотря на то, что они содержат одни и те же данные.

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

(Оба типа струнной конструкции неизменны, конечно)

3

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

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

0

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

2

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

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

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

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

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

Смежные вопросы