Saya sudah sering melihat ketentuan immutable
dan const
digunakan secara bergantian. Namun, dari pengalaman (kecil) saya, keduanya sangat berbeda dalam 'kontrak' yang mereka buat dalam kode:
Immutable membuat kontrak bahwa objek ini tidak akan berubah, apa pun (mis. Python tuple, string Java).
Const membuat kontrak bahwa dalam lingkup variabel ini tidak akan diubah (tidak ada janji apa pun tentang apa yang mungkin dilakukan utas lain terhadap objek yang ditunjuk selama periode ini, misalnya kata kunci C / C ++).
Jelas, keduanya tidak setara, kecuali bahasanya adalah single-threaded (PHP), atau memiliki sistem pengetikan linear atau uniquness (Clean, Mercury, ATS).
Pertama, apakah pemahaman saya tentang kedua konsep ini benar?
Kedua, jika ada perbedaan, mengapa mereka hampir secara eksklusif digunakan secara bergantian?
sumber
const
tidak ada di setiap bahasa, dan ketidakmampuan dan keabadian tidak ada di setiap bahasa sehingga membuat bahasa ini agonistik tidak berlaku. Ini hanya khusus bahasa di mana konsep-konsep ini berlaku.Jawaban:
Saya akan berbicara dengan C ++, di mana perbedaan ini paling relevan.
Seperti yang Anda catat dengan benar, kekekalan berarti bahwa suatu objek tidak dapat berubah sama sekali setelah penciptaannya. Penciptaan ini tentu saja dapat terjadi pada saat runtime, yaitu, suatu
const
objek tidak harus berupa konstanta waktu kompilasi. Dalam C ++, objek tidak dapat diubah jika (1) dan (2) atau (3) terpenuhi:Itu tidak memiliki anggota menyatakan
mutable
yang dimutasi olehconst
fungsi anggotaDinyatakan
const
const
fungsi anggota tidak digunakanconst_cast
untuk menghapusconst
kualifikasi untuk mengubah anggota mana punNamun, Anda juga dapat mempertimbangkan pengubah akses: jika suatu operasi secara internal mengubah sebuah instance, tetapi tidak memiliki efek pada keadaan instance yang dapat diamati melalui antarmuka publiknya, maka objek tersebut “secara logika tidak dapat diubah”.
Jadi C ++ menyediakan alat yang diperlukan untuk membuat objek yang tidak dapat diubah, tetapi seperti kebanyakan semua yang ada di C ++, alat tersebut hanya cukup memadai, dan membutuhkan ketekunan untuk benar-benar menggunakannya. Keadaan instance tidak harus terbatas pada variabel anggota instance — karena C ++ tidak menyediakan cara untuk menegakkan transparansi referensial, ia dapat menyertakan status global atau kelas juga.
const
juga memiliki fungsi lain di C ++: untuk memenuhi syarat referensi dan petunjuk. Sebuahconst
referensi dapat merujuk ke nonconst
objek. Adalah sah (meskipun tidak secara umum tidak perlu atau disarankan) untuk digunakanconst_cast
untuk memutasi suatu objek melaluiconst
referensi, jika dan hanya jika objek tersebut dinyatakan non-const
:Dan tentu saja itu perilaku yang tidak terdefinisi untuk bermutasi
const
objek:sumber
Berbicara untuk Java di mana kata kunci "final" mewakili "const", pertimbangkan:
Ini berarti
someone
TIDAK PERNAH bisa merujuk ke objek Orang lain. Namun, Anda masih dapat mengubah detail orang yang dirujuk. Misalnyasomeone.setMonthlySalary(10000);
Tapi, jika
someone
itu adalah objek "Immutable", salah satu dari yang berikut ini akan benar: (a) Anda tidak akan memiliki metode bernamasetMonthlySalary
(b) Memanggil setMonthlySalary akan selalu memberikan pengecualian sepertiUnsupportedOperationException
sumber
Objek yang tidak dapat diubah adalah objek yang tidak mengubah status setelah membuatnya. Sebagai contoh;
Dalam contoh ini objek myComplexStr tidak dapat diubah tetapi tidak konstan karena nilainya dihitung. Dan itu tidak berubah karena itu adalah string dan memiliki properti panjang statis dan tidak dapat berubah.
Objek Const umumnya digunakan untuk mengidentifikasi beberapa konstanta nyata yang nilainya diketahui sebelum kompilasi seperti Pi, "USA", "StackOverflow.com", nomor port, dan sebagainya.
Dari perspektif ini, Const berbeda dari objek yang tidak dapat diubah karena nilainya tidak dihitung oleh program.
Tetapi jika Anda berbicara tentang kata kunci "const" di C ++, Anda dapat mengatakan bahwa "const" digunakan untuk membuat objek yang tidak dapat diubah.
sumber
const
seperti itu adalah perilaku yang tidak ditentukan di mana pun itu dialokasikan, IIRC. Dan perilaku tidak terdefinisi lebih buruk daripada kesalahan spesifik yang dijamin akan terjadi. Ini berarti Anda tidak menggunakan C ++ lagi - C ++ tidak menyediakan sarana untuk mengubahconst
nilai (kecualimutable
anggota tentu saja, tetapi itu bukan poin Anda), jadi sejauh menyangkut C ++, Anda tidak dapat melakukannya. Apa implementasi spesifik terjadi untuk memungkinkan adalah masalah lain sepenuhnya (dan saya yakin Anda, jika Anda mengkompilasi dengan optimasi, aksi yang Anda tarik tidak akan mempengaruhi ekspresi yang digunakan nantipi
karena telah diganti).Ya tetapi pertanyaan kedua Anda menunjukkan bahwa Anda tidak memahami perbedaan-perbedaan ini.
const
di C ++ hanya digunakan untuk tingkat akses (itu berarti "read-only") , bukan untuk immutability. Ini menyiratkan bahwa akses itu sendiri benar-benar terpisah dari data. Misalnya Anda dapat memanipulasi beberapa data kemudian memaparkannya melalui referensi const. Aksesnya hanya baca, tetapi datanya sendiri, karena semua datam bisa berubah.const hanya membatasi akses jaminan, sementara ketidakmampuan (seperti dalam D misalnya) menyiratkan benar-benar tidak ada cara untuk mengubah data pada tahap apa pun dari kehidupan objek .
Sekarang, Anda dapat mensimulasikan imutabilitas dalam C ++ dengan memastikan beberapa data tidak mungkin diakses dengan cara lain selain const dan pastikan itu diinisialisasi kemudian tidak disentuh lagi. Tapi itu bukan jaminan yang kuat karena bahasa seperti D memberi Anda ketika Anda menandai data Anda sebagai tidak dapat diubah. Bahasa memastikan tidak mungkin sama sekali untuk melakukan operasi memodifikasi data itu, sementara di C ++ Anda masih berpotensi untuk mengubah data melalui casting dan mutability const jika benar-benar diperlukan.
Pada akhirnya, itu tidak sama sekali karena tidak menawarkan sama sekali jaminan yang sama.
sumber
Berbicara tentang JavaScript, kata kunci
const
danObject.freeze
const
berlaku untuk bindingvariables
. Ini menciptakan ikatan yang tidak berubah, Anda tidak dapat menetapkan nilai baru untuk itu.Object.freeze
bekerja pada nilai objek. Itu membuat objek tidak berubah . Yaitu, Anda tidak dapat mengubah propertinya.sumber
Dalam C ++ keduanya sama. Meskipun Anda dapat mengubah
const
objek jika Anda memiliki lokasi di memori dan izin OS untuk menulis ke memori itu.sumber
Dalam C, C ++ dan bahasa terkait, ada juga perbedaan antara objek menjadi const dan referensi Anda atau penunjuk ke objek menjadi referensi konstan.
Jika Anda mencoba untuk memodifikasi objek konstan Anda mendapatkan perilaku yang tidak terdefinisi. (Anda dapat mencoba untuk memodifikasi objek konstan misalnya dengan mengambil alamatnya, melemparkan alamat ke pointer non-const, dan kemudian menggunakan pointer non-const untuk memodifikasi objek).
Pointer atau referensi konstan di sisi lain hanya memberitahu kompiler bahwa Anda tidak dapat menggunakan pointer atau referensi ini untuk memodifikasi objek. Anda dapat melemparkan pointer atau referensi dan mencoba memodifikasi objek. Jika objek itu sendiri konstan, hal-hal buruk akan terjadi. Jika objek tidak benar-benar konstan, itu akan berubah. Ini tentu saja dapat membingungkan pengguna kode Anda dan sangat mungkin menyebabkan bug.
Dalam C, jika Anda menggunakan string literal seperti "Hello", lima karakter dan nol byte trailing sebenarnya konstan, tetapi Anda mendapatkan pointer non-const. Ide yang sangat buruk untuk menggunakan pointer non-const untuk mengubah objek.
Di C, Anda dapat memiliki pointer "constrict". Itu berarti objek yang ditunjuk sementara konstan. Jika objek diubah dengan cara apa pun saat pointer "const membatasi" dalam lingkup, Anda mendapatkan perilaku yang tidak ditentukan. Ini lebih kuat daripada pointer const yang hanya mencegah Anda mengubah objek melalui pointer ini.
sumber