So far I've told you that mutation
modifies the existing object.
But you can't really see the difference from what we've done with strings.
Where we'll really see the difference is when we introduce a new variable.
Let's go back to the example we had before,
and now we're going to add an extra assignment statement,
and we'll introduce a new variable.
Suppose we introduce the variable "q."
And we assign p to q, and that means the value of p,
which is the object that's this list,
is now what q will refer to.
The important thing here is after the assignment,
p and q refer to the same list.
Suppose we did an assignment statement
to modify the value of one of the elements of q.
Well, that will change element 4 of q,
so this is element 4 of q.
It will change that value
to the new exclamation point.
It also changed the value of p.
Even though the assignment statement didn't include p,
the fact that p and q refer to the same object
means that it changed the value of p.
To show you that things are different with strings,
let's try that with a string.
See if you can guess what happens when we try to use assignment
to replace the first letter in the string.
Let's run it to see what happens.
And what we get is an error,
and we get an error because the string is not mutable.
There's no way to change the value of the string,
and the error says there's no way to do assignment in a string,
that that type of object, because it's immutable, does not support assignment.
A key difference between mutable objects and immutable objects
is once an object is mutable,
then we have to worry about other variables that might refer to the same object.
We can change the value of that object,
and it affects not just the variable that we think we changed,
it affects the value of other variables as well.
Let's see an example of that.
I've initialized p to the list containing the strings "Hello."
Now I have an assignment that introduces the new variable q
and assigns p to that variable.
And we'll print out the values of p and q,
and we'll see that both p and q contain the string Hello.
But now let's change the value at position 0.
Now we have an assignment that stores
in the value at position 0 of p the letter y.
This changes the value of p.
What may be more surprising is this also changes the value of q.
Even though we didn't use q in the assignment,
it changed the value of q because q
refers to the same object as p.
حتى الآن، لقد أخبرتكم أن التعيين
يُعدل العنصر الموجود
لكن لا يمكنكم رؤية الإختلاف فيما
قمنا به مع السلاسل
نحن سوف نرى الإختلاف حقاً
عندما نقدم متغير جديد
هيا لنعد إلى المثال الذي كان لدينا سابقاً
والأن سنضيف سلسلة معينة جديدة
وسنُعرف متغير جديد
فلنفترض أننا عرفنا المتغير "q"
والأن نحن سنعين المتغير"p" إلى
المتغير "q"، وهذا يعني قيمة p
والذي سوف يشير إلي العنصر التي
تشير إليه هذه القائمة.
الشيء المهم هنا بعد التعيين
أن "p" و"q" تشير إلى نفس القائمة.
فلنفترض أننا قمنا بتعيين سلسلة
لكي نُعدل قيمة إحدى عناصر "q".
حسناً، هذا سوف يُغير العنصر الرابع من "q"
إذا هذا هو العنصر الرابع من "q".
سوف يغيير هذه القيمة
إلي علامة تعجب جديدة.
وقام أيضاً بتغيير قيمة "p".
حتى ولم تتضمن تعيين السلسلة المتغير "p"
الحقيقة أن المتغير "p" و "q"
يشيران إلى نفس العنصر
بمعنى أنه غير قيمة "p" أيضاً.
لنريك أن هذه الأشياء مختلفة
مع السلاسل
لنجرب ذلك مع سلسلة
أنظر إذا كنت سوف تتوقع ما يحدث
عندما نحاول إستخدام التعيين
لإستبدال الحرف الأول في السلسة
لنشغله ونرى ماذا سوف يحدث.
وما سوف نحصل عليه هو خطأ
ونحصل على هذا الخطاً
لأن السلسلة غير قابلة للتغيير
ليس هناك طريقة لتغيير قيمة هذه السلسة
والخطأ يقول أنه لا يوجد طريقة
لكي نقوم بالتعيين في السلسلة
إن هذا النوع من العناصر،
بسبب أنه لا يقبل التغيير لا يدعم التعيين.
الفرق الرئيسي بين العناصر
التي تقبل والتي لاتقبل التعيين
هو أنه عندما يصبح عنصر ما قابل للتغيير
علينا إذاً أن نقلق بشأن المتغيرات الأخري
والتي من الممكن أن تشير إلى نفس العنصر.
يمكننا تغير قيمة هذا العنصر
وهذا لا يؤثر فقط على المتغير
الذي نعتقد أننا قمنا بتغييره
لكن يؤثر أيضاً علي قيمة
المتغيرات الأخري أيضاً
لنلقي نظرة علي مثال عن هذا الأمر
لقد قمت بتعيين المتغير "p" إلي القائمة
التي تحتوي على سلسلة "Hello".
لدي الآن تعيين جديد يقدم
المتغير الجديد "q"
ويعين المتغير "p" إالي هذا المتغير الجديد
والأن سوف نقوم بطباعة قيمة كل من "p" و "q"
وسوف نرى أن قيمة كل من "p" و "q"
تحتوي على السلسلة "Hello".
ولكن الآن لنغير القيمة عند الموضع 0
لدي الآن تعيين والذي يخزن
الحرف "y" في قيمة الموضع 0 من المتغير "p"
هذا يغير قيمة المتغير "p"
والذي يبدو مدهشاً أكثر أنه
يغيير أيضاً قيمة "q"
علي الرغم أننا لم نشير إلي
المتغير "q" في التعيين
لقد تم تغيير قيمة المتغير "q" لآن "q"
تشير إلي نفس العنصر
الذي يشير إليه المتغير "p".
Finora ad ora abbiamo detto che la mutazione
modifica un oggetto esistente.
Ma non si può ancora vedere la differenza evidente con quello che facciamo con le stringhe.
Vedremo bene questa differenza quando introdurremo una nuova variabile.
Torniamo all'esempio precedente,
aggiungeremo ora un ulteriore assegnazione di variabile,
introducendo una nuova variabile.
Supponiamo di introdurre la viaribile 'q' .
Ed assegniamo 'p' a 'q' , che significa che il valore di 'p' ,
che sarebbe questo oggetto lista,
fa ora riferimento a 'q' .
La cosa importante qui avviene dopo l'assegnazione,
'p' e 'q' si riferiscono alla stessa lista.
Supponiamo di aver fatto una assegnazione
per modificare il valore di uno degli elementi di 'q' .
Bhé, questo cambierà l'elemento quattro di 'q' ,
quindi questo è l'elemento quattro di 'q' .
Cambierà il valore
con il punto esclamativo.
Cambierà anche il valore di 'p' .
Ma l'assegnazione non contiene in alcun modo 'p' ,
il fatto che 'p' e 'q' si riferiscano allo stesso oggetto
significa che è cambiato il valore di 'p' .
Per vedere come questo si comporti diversamente con le stringhe
proviamo a farlo con una stringa.
Vedete se riuscite ad indovinare cosa succede se assegniamo
un nuovo valore alla prima lettera della stringa.
Lanciamo il programma per vedere cosa succede.
Quello che otteniamo è un errore,
poiché la stringa è un oggetto immutabile.
Non c'è modo di cambiare il valore di una stringa,
e l'errore ci dice che non è possibile fare assegnazioni all'interno di una stringa,
a causa del tipo di oggetto, poiché è immutabile, non accetta l'assegnazione.
Una delle differenze principali tra oggetti mutabili e immutabili
è che se un oggetto è mutabile
dobbiamo fare attenzione alle altre variabili che potrebbero far riferimento allo stesso oggetto.
Possiamo cambiare il valore dell'oggetto,
e ciò cambierà non solo la variabile a cui noi pensiamo faccia riferimento
bensì tutte le altre variabili assegnate allo stesso oggetto.
Vediamo un esempiio.
Ho inizializzato 'p' assegnandolo alla lista che contiene 'Hello' .
Ora ho un'assegnazione che introduce la nuova variabile 'q'
e che assegna 'p' a quella variabile.
Stampiamo ora il valore di 'p' e 'q' ,
e vedremo che entrambe conterranno la stringa 'Hello' .
Cambiamo ora il valore della posizione zero.
Avremmo una assegnazione che memorizza
nella posizione zero di 'p' la lettera 'y' .
Questo cambia il valore di 'p' .
Cosa sorprendente potrebbe essere che questo cambia anche il valore di 'q' .
Anche se 'q' non compare nell'assegnazione ,
lo cambia in quanto 'q'
si riferisce allo stesso oggetto di 'p' .
ミューテーションが現在のオブジェクトを
変更するものだと解説してきました
しかし文字列を使って行ったものとの違いを
確かめることはできません
新たな変数を挿入することで
違いを確認することができます
前の例に戻りましょう
代入文を追加して新しい変数を挿入します
変数qを挿入すると仮定しましょう
そしてpをqに代入します
つまりこのリストのオブジェクトであるpの値が
qが参照するものになるということです
ここで重要なのは代入後に
pとqが同じリストを参照しているということです
qの要素の値を1つ変更する代入文を
行ったと仮定します
これでqの要素4が変更されます
これがqの要素4です
その値を新たな感嘆符に変更します
pの値も変更されます
代入文にはpが含まれていませんが
pとqは同じオブジェクトを参照しているので
pの変数も変更されることになります
文字列を使用した場合は異なることを確認するために
文字列でこれを試してみましょう
文字列で最初の文字を置き換えるために
代入を使用した場合
何が起きるか予想してみてください
実行してみましょう
エラーが出ました
文字列が変更できないものだったからです
文字列の値を変更する方法はありません
文字列に代入する方法はありませんという
エラーが表示されます
これは不変的なオブジェクトなので
代入に対応していません
変更できるオブジェクトと
できないオブジェクトの重要な違いは
オブジェクトが変更できる場合は
同じオブジェクトを参照しているかもしれない
他の変数に注意しなければならないことです
そのオブジェクトの値を変えます
変更したと思われる変数だけでなく
他の変数の値にも同じように作用します
この例を確かめてみましょう
pを文字列Helloを含むリストに設定します
新しい変数qを挿入しその変数にpを代入します
pとqの値を出します
pとq両方が文字列Helloを含んでいると
確認できますね
しかしここでゼロの位置にある値を
変更してみましょう
pのゼロの位置にある値に
文字Yを保持する代入を行います
これによってpの値が変更されます
驚くことにqの値も変更されます
代入でqを使用していないにもかかわらず
qの値が変更されました
qがpと同じオブジェクトを参照しているからです
Eu falei para você que mutação
modifica um objeto existente.
Mas, de fato, você ainda não pode de fato ver a diferença entre isso e o que fizemos com strings.
Onde você irá perceber a diferença é quando introduzimos uma nova variável.
Vamos voltar ao exemplo que vimos anteriormente,
mas agora vamos adicionar um comando de atribuição extra,
e vamos introduzir uma nova variável.
Suponha que introduzimos a variável q,
e atribuímos p a q -- isso significa que o valor de p,
que é o objeto que é esta lista,
é agora aquele que q referencia.
O importante aqui é que, depois da atribuição,
p e q referenciam a mesma lista.
Suponha que fazemos um comando de atribuição
para modificar o valor de um dos elementos de q.
Bem, isto muda o elemento 4 de q --
então, este é o elemento 4 de q,
e isso muda este valor,
para o novo ponto de exclamação.
Isso muda também o valor de p:
mesmo que o comando de atribuição não mencione p,
o fato de que p e q referenciam o mesmo objeto
significa que isto altera o valor de p.
Para mostrar a você que as coisas são diferentes com strings,
vamos tentar isso com uma string.
Veja se você adivinha o que acontece quanto tentamos usar atribuição
para substituir a primeira letra da string.
Vamos executar, para ver o que acontece.
E o que obtemos é um erro,
e obtemos um erro porque uma string não é mutável.
Não existe uma maneira de mudar o valor de uma string,
e o erro diz que não há como fazer uma atribuição a uma string --
que esse tipo de objeto, como é imutável, não suporta atribuição.
Uma diferença fundamental entre objetos mutáveis e objetos imutáveis
é que, se o objeto for mutável,
então temos que nos preocupar com outras variáveis que possam referenciar esse mesmo objeto.
Podemos modificar o valor desse objeto,
e isso afetar não apenas a variável que pensamos estar alterando,
mas afetar também outra variáveis.
Vamos ver um exemplo disso.
Eu inicializei p com uma lista contendo as strings 'H', 'e', 'l', 'l', 'o'.
Agora, eu tenho uma atribuição que introduz uma nova variável q,
e atribuo p a esta variável.
E vamos imprimir os valores de p e de q,
e var que ambas, p e q, contêm a string "Hello".
Mas, agora, vamos modificar o valor na posição 0.
Agora, temos uma atribuição que armazena,
na posição 0 de p, a letra 'Y'.
Isso modifica o valor de p.
O que pode ser surpresa é que isso também altera o valor de q.
Mesmo que não tenhamos usado q na atribuição,
isso podifica o valor de q, porque q
referencia o mesmo objeto que p.
现在 大家都已知道 链表可变
能够改变已有对象的值
但链表和字符串的不同还未真正体现
引入新变量能够让我们看清链表和字符串的差别何在
回到之前的例子
现在 我将加入另一句赋值语句
引入新变量
假定新变量为q
将p的值赋予q
p的值是这个链表
现在由q来指代
记住 执行这句语句之后
p和q指代同一个链表
假定有赋值语句
改变变量q中一个元素的值
假定改变q中元素4的值
就是这个元素
改变为
惊叹号
p的值也同时改变
尽管赋值语句没有提到p
但正因为p和q指代同一个链表
就算没提到p p的值也发生了改变
字符串的话会如何呢
我们用字符串试一试
我们改变字符串第一个字母值时 大家能否猜出
会出现什么情况
运行 看一下
结果是错误
错误原因是字符串不可变
我们不能改变字符串的值
运行结果也显示 不能在字符串中运行赋值语句
因为字符串不可变 不支持赋值语句
可变和不可变对象的主要区别在于
如果对象可变
我们必须对其他变量加以考虑 看它们是否指代同一个对象
因为当改变某一目标值的时候
影响的不仅仅是这一变量
还会改变其他变量的值
举个例子
初始化变量p包含字符串Hello
现在引入了新变量q
p等于q
打印p和q
可以看到这两个变量都包含字符串Hello
现在 我们改变位置0的值
将p位置0的值
改为字母y
这改变了p的值
但同时也改变了q的值
尽管赋值语句完全没有提及q
q的值发生改变 是因为
q和p指代同一对象
目前為止我教了你們 mutation
修改已存在的物件 (object)
但是你還無法真正了解,跟處理字串有甚麼不同
引入新變數,能夠讓我們真正地了解它們之間的差異
回到之前的例子
現在我要加入一個額外的指定陳述
引入新變數
假定新變數為 q
將 p 的值指定給 q
意思是 p 的值,這個列表物件
q 現在指向了它
重要的是,執行指定之後
p 和 q 指向同一個列表
假定執行指定陳述
修改 q 中一個元素的值
嗯,改變 q 的第 4 個元素
這是 q 的第 4 個元素
把值改為
新的驚嘆號
p 的值也同時被改變
即使指定陳述沒有提及 p
事實上 p 和 q 指向同一個物件
所以也改變了 p 的值
字串則不是如此
我們用字串試試看
大家能否猜出,以指定來改變字串的第一個字母
會出現什麼情況
執行看看,會發生什麼事?
結果得到錯誤 (error)
錯誤的原因,是因為字串不是變種的 (not mutable)
我們不能改變字串的值
error 說:不可以在字串裡做指定
因為這類的物件是不可變的、不支持指定陳述
變種的 (mutable) 物件和非變種 (immutable) 的物件的
主要區別在於
一旦物件是變種的 (mutable)
我們必須顧慮其他的變數,看看它們是否指向同一個物件
我們可以改變某物件的值
它影響的不僅是我們改變的這個變數
還會改變其他變數的值
舉個例子
初始化 p 為包含字串 'Hello' 的列表
現在有個陳述,引入了新變數 q
將 p 指定給 q
印出 p 和 q 的值
可以看到變數 p 和 q 都包含字串 'Hello'
但是現在我們改變位置 0 的值
做一個指定
將 p 的位置 0 的值儲存為字母 'Y'
這改變了 p 的值
但令人驚訝的是,這同時改變了 q 的值
即使指定陳述完全沒有提及 q
q 的值發生改變是因為
q 和 p 指向同個物件