Değişmez ne anlama geliyor?


104

Bir dizge değişmez ise, bu şu anlama mı gelir .... (JavaScript varsayalım)

var str = 'foo';

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

alert(str); // foo

Bu, bir dizedeki yöntemleri çağırırken, değiştirilmiş dizgeyi döndüreceği, ancak ilk dizeyi değiştirmeyeceği anlamına mı geliyor?

Dize değiştirilebilir olsaydı, bu 2.'nin alert()de döneceği anlamına oomı geliyor?

Yanıtlar:


105

Bu, nesneyi bir kez başlattığınızda özelliklerini değiştiremeyeceğiniz anlamına gelir. İlk uyarınızda foo'yu değiştirmiyorsunuz. Yeni bir dizi oluşturuyorsunuz. Bu yüzden ikinci uyarınızda oo yerine "foo" gösterecektir.

Bu, bir dizedeki yöntemleri çağırırken, değiştirilmiş dizgeyi döndüreceği, ancak ilk dizeyi değiştirmeyeceği anlamına mı geliyor?

Evet. Dizeyi oluşturulduktan sonra hiçbir şey değiştiremez. Şimdi bu, strdeğişkene yeni bir dizge nesnesi atayamayacağınız anlamına gelmez . Str'nin başvurduğu geçerli nesneyi değiştiremezsiniz.

Dize değiştirilebilir olsaydı, bu 2. uyarı () 'nın da oo döndüreceği anlamına mı gelir?

Teknik olarak hayır, çünkü alt dize yöntemi yeni bir dize döndürür. Bir nesneyi değiştirilebilir yapmak, yöntemi değiştirmez. Değiştirilebilir hale getirmek, teknik olarak, alt dizgenin yeni bir tane oluşturmak yerine orijinal dizeyi değiştirmesini sağlayacak şekilde yapabileceğiniz anlamına gelir.


Aynı dize değiştirilir ve atanırsa, dizeyi güncelleyecektir var str = 'foo'; str = str.substr (1)); // oo alert (str); // oo
Ashwin G

Aşağıdaki kod ne olacak? Dize değeri şimdi değiştirildi. var name = "Santosh"; console.log (name.substr (0,2)); var name = "kumar" console.log (ad); Hala nasıl değişmez
Santosh

97

Daha düşük bir seviyede, değişmezlik, dizenin saklandığı belleğin değiştirilmeyeceği anlamına gelir. Bir dizi oluşturduğunuzda "foo", değeri saklamak için bir miktar bellek ayrılır "foo". Bu hafıza değiştirilmeyecek. Dizeyi, örneğin ile değiştirirseniz, substr(1)yeni bir dizge oluşturulur ve belleğin farklı bir bölümü depolanacak şekilde tahsis edilir "oo". Şimdi hafızada iki diziniz var "foo"ve "oo". "foo"Artık kullanmayacak olsanız bile , çöp toplanana kadar etrafta kalacaktır.

Dize işlemlerinin nispeten pahalı olmasının bir nedeni.


1
Sayılar da değişmezdir.
RN Kushwaha

3
2015'ten merhaba !! "Daha düşük bir seviyede, değişmezlik, dizginin saklandığı belleğin değiştirilmeyeceği anlamına gelir." --- bu çok kısıtlayıcı ve kulağa doğru gelmiyor. Değişmezlik yalnızca kullanıcı alanıyla ilgilidir, sanal bellek, dil spesifikasyon değişmezleri tutulur saklanmaz bellek ayırıcının istediği şekilde değiştirilebilir.
zerkms

2
Bu cevap, kabul edilen cevaptan daha mantıklı.
Ejaz Karim

Ama var str = 'foo'; str = 'bar' ile değiştirebilirim. str değeri bu şekilde değiştirildi değil mi?
Hacker

@Hacker Hayır. Değişkene bellekte yeni bir konuma işaret eden yeni bir dizge atadınız.
deceze

13

Değişmez, değiştirilemeyen veya değiştirilemeyen anlamına gelir.

Dolayısıyla, bir dizeye bir değer atadığınızda, bu değer değiştirilmesinin aksine sıfırdan oluşturulur. Böylece aynı dizeye her yeni değer atandığında bir kopya oluşturulur. Yani gerçekte, orijinal değeri asla değiştirmiyorsunuz.


9

JavaScript konusunda emin değilim, ancak Java'da dizeler "Dize Sabit Havuzu" ile değişmezliğe ek bir adım atıyor. Dizeler, dize değişmezleri ( "foo") veya bir Stringsınıf yapıcısı ile oluşturulabilir. Dize değişmezleri ile oluşturulan dizeler, Dize Sabit Havuzunun bir parçasıdır ve aynı dize değişmezi her zaman havuzdaki aynı bellek adresi olacaktır.

Misal:

    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

Yukarıdaki her iki lit1ve lit2aynı dize kullanarak inşa edilir onlar böylece aynı bellek adresinde ediyoruz işaret; lit1 == lit2sonuçlanırtrue , çünkü bunlar tamamen aynı nesnelerdir.

Ancak, conssınıf yapıcısı kullanılarak oluşturulur. Parametre aynı dize sabiti olmasına rağmen, kurucu için yeni bellek ayırır; bu cons, aynı verileri içermesine rağmen ve ile consaynı nesne değildir .lit1lit2

Elbette, üç dizenin tümü aynı karakter verilerini içerdiğinden, equalsyöntemi kullanmak doğru döndürür.

(Elbette her iki tür ip yapımı da değişmezdir)


3

Değişmez, değerin değiştirilemeyeceği anlamına gelir. Bir kez oluşturulduktan sonra bir dizge nesnesi değişmez olarak değiştirilemez. Bir dizenin bir alt dizesini talep ederseniz, istenen parçayla yeni bir Dize oluşturulur.

Bunun yerine, Dizeleri işlerken StringBuffer kullanmak, işlemi daha verimli hale getirir, çünkü StringBuffer dizeyi karakter dizisinin kapasitesini ve dizinin uzunluğunu tutmak için değişkenlerle bir karakter dizisinde depolar (String in a char array form)


3

Değişebilirliğin metin kitabı tanımı yükümlüdür veya değişiklik veya değişikliğe tabidir. Programlamada, bu sözcüğü, durumlarının zaman içinde değişmesine izin verilen nesneleri ifade etmek için kullanırız. Değişmez bir değer tam tersidir - yaratıldıktan sonra asla değişemez.

Bu tuhaf görünüyorsa, her zaman kullandığımız değerlerin çoğunun aslında değişmez olduğunu hatırlatmama izin verin.

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

İkinci satırın ifadedeki dizeyi hiçbir şekilde değiştirmediğini öğrenince kimsenin şaşırmayacağını düşünüyorum. Aslında, hiçbir dize yöntemi üzerinde çalıştıkları dizeyi değiştirmez, hepsi yeni dizeler döndürür. Bunun nedeni, dizelerin değişmez olmasıdır - değişemezler, biz sadece yeni dizeler yapabiliriz.

Dizeler, JavaScript'te yerleşik olan tek değişmez değerler değildir. Sayılar da değişmezdir. 2 + 3 ifadesini değerlendirmenin 2 sayısının anlamını değiştirdiği bir ortam hayal edebiliyor musunuz? Kulağa saçma geliyor, ancak bunu her zaman nesnelerimiz ve dizilerimizle yapıyoruz.


2

Dizelerden yığınlara ... Eric Lippert'in blogundan alınan anlaşılması kolay bir örnek :

C # 3.0'da A * Kullanarak Yol Bulma, Bölüm İki ...

System.Collections.Generic.Stack gibi değiştirilebilir bir yığın açıkça uygun değildir. Var olan bir yolu alabilmek ve ondan son elemanının tüm komşuları için yeni yollar oluşturabilmek istiyoruz, ancak yeni bir düğümü standart yığına itmek yığını değiştirir. İtmeden önce yığının kopyalarını çıkarmamız gerekirdi, ki bu aptalca çünkü o zaman tüm içeriğini gereksiz yere kopyalıyor olurduk.

Değişmez yığınlarda bu sorun yoktur. Değişmez bir yığın üzerine itmek, yalnızca kuyruğu olarak eskisine bağlanan yepyeni bir yığın oluşturur. Yığın değişmez olduğundan, başka bir kodun gelip kuyruk içerikleriyle uğraşma tehlikesi yoktur. Kalbinizin içeriği için eski yığını kullanmaya devam edebilirsiniz.

Değişmezliği anlamak konusunda derinlere inmek için, Eric'in bununla başlayan gönderilerini okuyun:

C # Birinci Bölümde Değişmezlik: Değişmezlik Türleri


Bu alıntı garip bir iddia içeriyor - yığın veri yapısının (aslında kuyruk paylaşımlı çoklu yığınlar) bir bütün olarak değiştirilebilir bir yapı olduğu - her push veya pop yapıyı değiştiriyor. Yalnızca tek tek öğeler değişmezdir. Ve prensip olarak, aynı yapıya sahip olabilirsiniz, ancak değişken unsurlarla. Bu, geri alınamaz birleşim bulma IIRC'nin bazı varyasyonlarında olur. Değişmezliğin büyük avantajları vardır, ancak bir veri yapısının bir kısmını veya tamamını bir optimizasyon olarak paylaşmak değişkenler ile mükemmel şekilde mümkündür. Diğer referanslar için görünürde değişmezlik istiyor olsanız bile, gerektiğinde her zaman yazma üzerine kopyalayabilirsiniz.
Steve314

0

Bu kavramı kavramanın bir yolu, javascript'in tüm nesnelere nasıl davrandığına bakmaktır, bu da referans olarak. Bu, tüm nesnelerin somutlaştırıldıktan sonra değiştirilebilir olduğu anlamına gelir, bu, yeni yöntemler ve özelliklerle bir nesne ekleyebileceğiniz anlamına gelir. Bu önemlidir, çünkü bir nesnenin değişmez olmasını istiyorsanız, nesne somutlaştırıldıktan sonra değiştirilemez.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.