Apa artinya kekal?

103

Jika sebuah string tidak dapat diubah, apakah itu berarti .... (mari kita asumsikan JavaScript)

var str = 'foo';

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

alert(str); // foo

Apakah itu berarti, ketika memanggil metode pada sebuah string, itu akan mengembalikan string yang dimodifikasi, tetapi tidak akan mengubah string awal?

Jika string itu bisa berubah, apakah itu berarti yang ke-2 alert()akan kembali oojuga?

alex
sumber

Jawaban:

104

Ini berarti bahwa setelah Anda membuat instance objek, Anda tidak dapat mengubah propertinya. Dalam peringatan pertama Anda, Anda tidak mengubah foo. Anda membuat string baru. Inilah sebabnya mengapa pada peringatan kedua Anda akan menampilkan "foo", bukan oo.

Apakah itu berarti, ketika memanggil metode pada sebuah string, itu akan mengembalikan string yang dimodifikasi, tetapi tidak akan mengubah string awal?

Iya. Tidak ada yang bisa mengubah string setelah dibuat. Sekarang ini tidak berarti bahwa Anda tidak dapat menetapkan objek string baru ke strvariabel. Anda tidak bisa mengubah objek saat ini yang dirujuk str.

Jika string itu bisa berubah, apakah itu berarti peringatan ke-2 () akan mengembalikan oo juga?

Secara teknis, tidak, karena metode substring mengembalikan string baru. Membuat objek bisa berubah, tidak akan mengubah metode. Membuatnya bisa berubah berarti secara teknis, Anda bisa membuatnya sehingga substring akan mengubah string asli daripada membuat yang baru.

kemiller2002
sumber
String yang sama jika diubah dan ditetapkan, akan memperbarui string var str = 'foo'; str = str.substr (1)); // oo alert (str); // oo
Ashwin G
Bagaimana dengan kode di bawah ini. Nilai string diubah sekarang. var name = "Santosh"; console.log (name.substr (0,2)); var name = "kumar" console.log (nama); Bagaimana itu masih tetap
Santosh
97

Pada tingkat yang lebih rendah, kekekalan berarti bahwa memori tempat string disimpan tidak akan diubah. Setelah Anda membuat string "foo", beberapa memori dialokasikan untuk menyimpan nilainya "foo". Memori ini tidak akan diubah. Jika Anda memodifikasi string dengan, katakanlah, substr(1)string baru dibuat dan bagian memori yang berbeda dialokasikan yang akan disimpan "oo". Sekarang Anda memiliki dua string dalam memori, "foo"dan "oo". Bahkan jika Anda tidak akan menggunakannya "foo"lagi, itu akan bertahan sampai sampah dikumpulkan.

Salah satu alasan mengapa operasi string relatif mahal.

menipu
sumber
1
Angka juga tidak bisa diubah.
RN Kushwaha
3
halo dari 2015 !! "Pada tingkat yang lebih rendah, keabadian berarti bahwa memori tempat string disimpan tidak akan diubah." --- ini terlalu membatasi dan kedengarannya tidak benar. Keabadian hanya tentang userland, memori virtual dapat diubah sesuai dengan pengalokasi memori segera setelah invarian spesifikasi bahasa disimpan.
zerkms
2
Jawaban ini lebih logis dari pada jawaban yang diterima.
Ejaz Karim
Tapi saya bisa melakukan seperti var str = 'foo'; saya dapat memodifikasi melalui str = 'bar'. nilai str diubah dengan cara ini kan?
Hacker
@Hacker Tidak. Anda telah menetapkan string baru ke variabel yang menunjuk ke lokasi baru di memori.
menipu
13

Tidak dapat diubah artinya yang tidak dapat diubah atau dimodifikasi.

Jadi ketika Anda menetapkan nilai ke string, nilai ini dibuat dari awal sebagai lawan diganti. Jadi setiap kali nilai baru diberikan ke string yang sama, salinan dibuat. Jadi kenyataannya, Anda tidak pernah mengubah nilai aslinya.

SoftwareGeek
sumber
9

Saya tidak yakin tentang JavaScript, tetapi di Java, string mengambil langkah tambahan menuju keabadian, dengan "String Constant Pool". String dapat dibangun dengan string literals ( "foo") atau dengan Stringkonstruktor kelas. String yang dibuat dengan string literal adalah bagian dari String Constant Pool, dan string literal yang sama akan selalu menjadi alamat memori yang sama dari kumpulan tersebut.

Contoh:

    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

Di atas, keduanya lit1dan lit2dibangun menggunakan string literal yang sama, jadi mereka menunjuk ke alamat memori yang sama; lit1 == lit2menghasilkan true, karena mereka adalah objek yang persis sama.

Namun, consdibangun menggunakan konstruktor kelas. Meskipun parameternya adalah konstanta string yang sama, konstruktor mengalokasikan memori baru untuk cons, artinya consbukan objek yang sama dengan lit1dan lit2, meskipun berisi data yang sama.

Tentu saja, karena ketiga string semuanya berisi data karakter yang sama, menggunakan equalsmetode ini akan mengembalikan nilai true.

(Kedua jenis konstruksi senar tidak dapat diubah, tentu saja)

Brian S
sumber
3

Immutable artinya nilainya tidak bisa diubah. Setelah dibuat, objek string tidak dapat dimodifikasi karena tidak dapat diubah. Jika Anda meminta substring dari sebuah string, String baru dengan bagian yang diminta dibuat.

Menggunakan StringBuffer sambil memanipulasi Strings malah membuat operasi lebih efisien karena StringBuffer menyimpan string dalam larik karakter dengan variabel untuk menampung kapasitas larik karakter dan panjang larik (String dalam bentuk larik karakter)

Nataraj
sumber
3

Definisi mutabilitas dalam buku teks bertanggung jawab atau dapat berubah atau diubah. Dalam pemrograman, kami menggunakan kata tersebut untuk mengartikan objek yang statusnya diizinkan untuk berubah seiring waktu. Nilai yang tidak berubah adalah kebalikannya - setelah dibuat, nilai tidak akan pernah bisa berubah.

Jika ini tampak aneh, izinkan saya mengingatkan Anda bahwa banyak nilai yang kita gunakan sepanjang waktu ternyata tidak dapat diubah.

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

Saya pikir tidak ada yang akan terkejut mengetahui bahwa baris kedua sama sekali tidak mengubah string dalam pernyataan. Faktanya, tidak ada metode string yang mengubah string tempat mereka beroperasi, mereka semua mengembalikan string baru. Alasannya adalah karena string tidak dapat diubah - string tidak dapat berubah, kita hanya dapat membuat string baru.

String bukan satu-satunya nilai tetap yang dibangun ke dalam JavaScript. Angka juga tidak bisa diubah. Dapatkah Anda membayangkan lingkungan di mana mengevaluasi ekspresi 2 + 3 mengubah arti angka 2? Kedengarannya tidak masuk akal, namun kami melakukan ini dengan objek dan array kami sepanjang waktu.

ahmed khattab
sumber
2

Dari string ke tumpukan ... contoh sederhana untuk dipahami diambil dari blog Eric Lippert :

Pencarian Jalur Menggunakan A * di C # 3.0, Bagian Kedua ...

Tumpukan yang bisa berubah seperti System.Collections.Generic.Stack jelas tidak cocok. Kami ingin dapat mengambil jalur yang ada dan membuat jalur baru darinya untuk semua tetangga dari elemen terakhirnya, tetapi mendorong node baru ke tumpukan standar mengubah tumpukan. Kami harus membuat salinan dari tumpukan sebelum mendorongnya, yang konyol karena kami akan menduplikasi semua isinya secara tidak perlu.

Tumpukan yang tidak dapat diubah tidak memiliki masalah ini. Mendorong ke tumpukan yang tidak dapat diubah hanya akan membuat tumpukan baru yang terhubung ke tumpukan lama sebagai ekornya. Karena tumpukan tidak dapat diubah, tidak ada bahaya beberapa kode lain yang datang dan mengacaukan konten ekor. Anda dapat terus menggunakan tumpukan lama sesuka hati Anda.

Untuk lebih dalam memahami keabadian, baca posting Eric dimulai dengan yang ini:

Kekekalan dalam C # Bagian Satu: Jenis Kekekalan

Leniel Maccaferri
sumber
Kutipan itu berisi klaim aneh - bahwa struktur data tumpukan (sebenarnya beberapa tumpukan dengan tail-sharing), secara keseluruhan, adalah struktur yang bisa berubah - setiap push atau pop mengubah struktur. Hanya item individu yang tidak dapat diubah. Dan pada prinsipnya, Anda bisa memiliki struktur yang sama tetapi dengan elemen yang bisa berubah. Hal ini terjadi dalam beberapa variasi IIRC union-find yang tidak dapat dibatalkan. Kekekalan memiliki keuntungan besar, tetapi berbagi sebagian atau seluruh struktur data sebagai pengoptimalan sangat mungkin dilakukan dengan mutable. Bahkan jika Anda menginginkan ketetapan yang nyata untuk referensi lain, Anda selalu dapat menyalin-saat-menulis sesuai kebutuhan.
Steve314
0

Salah satu cara untuk memahami konsep ini adalah dengan melihat bagaimana javascript memperlakukan semua objek, yaitu dengan referensi. Artinya semua objek dapat berubah setelah dibuat instance-nya, ini berarti Anda dapat menambahkan objek dengan metode dan properti baru. Ini penting karena jika Anda ingin objek menjadi tidak berubah, objek tidak dapat berubah setelah dibuat instance-nya.

Rick
sumber