Judul yang sangat samar tapi saya tidak bisa memikirkan cara yang lebih baik untuk mengatakannya. Tapi, seperti contohnya, pikirkan tentang arah pergerakan karakter dalam permainan. Rasanya agak salah menggunakan string dan kemudian melakukan hal-hal seperti if(character.direction == "left")
. Sepertinya saya bahwa ia meninggalkan terlalu banyak ruang untuk kesalahan konyol, seperti sengaja menggunakan Left
atau l
atau apa pun bukan left
. Apakah kecurigaan saya benar? Jika demikian, apa cara yang disukai untuk mencapai sesuatu seperti ini?
19
bash
,.Jawaban:
Jika bahasa yang Anda gunakan mendukung penggunaan enum, saya akan menggunakannya. Ini memungkinkan Anda membatasi jumlah opsi yang tersedia untuk jenis tertentu. misalnya di Jawa:
sumber
enum
seperti java. Banyak bahasa (mis. VBA) milikienum
, tetapi ini mungkin bukan pilihan terbaik karena tidak memiliki pembuktian yang sama di masa depan. Lihat jawaban saya untuk beberapa diskusi tentang mengapaenum
sendirian adalah solusi yang tidak lengkap, sering rapuh, dan spesifik bahasa.Praktek yang mengerikan untuk menggunakan string literal (atau angka ajaib) dalam kode.
Enum baik, atau paling tidak menggunakan konstanta (enum tentu saja hanya tipe pembungkus untuk satu atau lebih konstanta terkait).
Peralihan sederhana ini memiliki begitu banyak keuntungan sehingga saya bahkan tidak tahu harus mulai dari mana menjelaskannya (setidaknya bukan tanpa kopi lagi). Baca tentang angka ajaib, itu konsep yang persis sama, hanya diterapkan pada nilai angka dan bukan nilai string.
Ini satu ref cepat, saya yakin ada ratusan lebih: /programming/47882/what-is-a-magic-number-and-why-is-it-bad
sumber
Jawaban singkat: Ya, string tidak ideal untuk tugas apa pun selain menyimpan dan mengakses urutan karakter tekstual, dan bahkan jika bit yang mendasari abstraksi adalah string, ada manfaat untuk merujuknya sebagai variabel atau konstanta .
Jawaban panjang: sebagian besar bahasa menawarkan jenis yang lebih dekat ke domain masalah Anda, dan meskipun tidak, mereka mungkin memiliki beberapa metode yang dapat Anda definisikan
left
sebagai entitas yang berbeda dariright
(dll.). Mengubahnya menjadi string dengan menggunakan"left"
hanyalah kehilangan bahasa dan fungsi IDE yang bermanfaat seperti pengecekan kesalahan. Bahkan jika Anda harus menggunakannyaatau sesuatu yang setara, itu memiliki keuntungan menggunakan string ketika Anda merujuknya di kode Anda. Sebagai contoh,
akan dideteksi sebagai kesalahan waktu kompilasi (kasus terbaik, java, dan semacamnya) atau ditandai oleh IDE apa pun yang bernilai bitnya salah (kasus terburuk, dasar, dan semacamnya).
Selain itu, memiliki gagasan
left
sebagai entitas yang dapat dirujuk akan membantu Anda mengakomodasi arah apa pun yang Anda putuskan untuk digunakan dengan tipe arah. Dengan menggunakan"left"
, arahan berkomitmen untuk menjadi aString
. Jika Anda menemukan atau membuat abstraksi yang lebih baik untuk jenis ini, Anda perlu menelusuri seluruh badan kode Anda untuk mengubah setiap instance"left"
. Konstanta atau variabel tidak akan memerlukan perubahan apa pun jika jenisnya dielaborasi.Jenis yang Anda inginkan adalah khusus untuk domain Anda. Apa yang akan dilakukan perencanaan kode Anda dengan kode Anda
left
? Mungkin Anda ingin mencerminkan sumbu x dari tekstur atau sprite yang menghadap ke kiri atau bergerak maju; Jika demikian, Anda mungkin ingin membuatleft
objek dengan properti atau metode yang mencerminkan perilaku itu, denganright
objek Anda memiliki hasil yang berlawanan tanpa cermin. Anda dapat melakukan logika itu pada objek yang mewakili sprite atau tekstur, dalam hal ini Anda akan menderita karena menggunakan"left"
bukanleft
karena alasan yang disebutkan di atas.Di Jawa (dan mungkin bahasa lain yang belum saya kenal),
enum
adalah alternatif yang baik karena di Jawa,enum
sama bermanfaatnyafinal class
dengan serangkaian contoh yang terbatas. Anda dapat mendefinisikan perilaku jika Anda membutuhkannya, dan Anda dapat beralih ke kelas terbuka tanpa kerepotan di luar file yang menyatakanenum
, tetapi banyak bahasa melihatenum
tipe primitif atau memerlukan sintaks khusus untuk digunakan. Itu bocorenum
ke kode yang tidak memiliki bisnis dengan itu dan mungkin perlu diperbaiki nanti. Pastikan Anda memahami konsep bahasaenum
Anda sebelum mempertimbangkan opsi.sumber
Anda tidak menentukan bahasa Anda, tetapi untuk memberikan jawaban umum, Anda harus menggunakan string ketika Anda benar-benar membutuhkan teks, bukan untuk mewakili sesuatu. Contoh yang Anda berikan misalnya tidak akan diterima dalam perangkat lunak produksi.
Setiap bahasa memiliki berbagai tipe data dasar dan Anda harus menggunakan yang paling sesuai untuk tugas tersebut. Untuk menggunakan contoh Anda, Anda bisa menggunakan konstanta numerik untuk mewakili status yang berbeda. Jadi kiri dapat memiliki nilai nol dan kanan akan menjadi satu. Selain alasan yang Anda sebutkan, nilai numerik membutuhkan lebih sedikit ruang (memori) dan selalu lebih cepat untuk membandingkan angka daripada membandingkan beberapa string karakter.
Seperti yang disarankan, gunakan enumerasi jika bahasa Anda memungkinkan. Dalam contoh spesifik Anda, itu jelas pilihan yang lebih baik.
sumber
if (uppercase(foo) == "LEFT")
Cukup gunakan tipe data yang masuk akal dalam situasi Anda.
Penggunaan
string
tipe ini sebagai komunikasi inter / intra-aplikasi yang mendasarinya secara inheren bukan masalah. Bahkan, kadang-kadang lebih disukai menggunakan string: Jika Anda memiliki API publik, dapat diinginkan untuk nilai masuk dan keluar dari API agar dapat dibaca oleh manusia. Ini memudahkan orang yang menggunakan API Anda untuk belajar dan debug.Masalah sebenarnya dengan kode Anda terletak pada pengulangan nilai.
Jangan lakukan ini:
Jika Anda membuat kesalahan ketik pada salah satu dari persyaratan ini atau penggunaan "kiri" lainnya di suatu tempat, Anda mungkin tidak dapat secara efektif melakukan pencarian berdasarkan basis kode untuk itu, karena Anda salah ketik!
Alih-alih, kode terhadap enumerasi atau konstanta - tergantung pada yang mendukung tipe data yang Anda butuhkan dalam bahasa yang Anda gunakan.
Itu berarti
LEFT
harus ditugaskan-ke sekali dan hanya sekali dalam aplikasi Anda. Dan, sisa kode Anda harus memanfaatkan enum atau konstanta tersebut:Ini juga memungkinkan Anda untuk lebih mudah mengubah tipe data yang Anda gunakan untuk arah Anda nanti, jika Anda mau.
sumber
Apakah ini praktik yang buruk?
Mungkin ya, tapi itu tergantung pada apa apa yang Anda lakukan, dan juga pada bahasa pemrograman yang Anda gunakan.
Dalam contoh Anda, kami dapat menyimpulkan bahwa ada serangkaian nilai yang kecil dan tetap untuk selamanya yang bisa diambil oleh suatu arah. Dalam hal ini, tidak ada keuntungan dalam menggunakan string, dan beberapa kerugian yang pasti. Untuk contoh ini:
enum
jenis akan lebih baik, jika bahasa pemrograman Anda mendukung ini.Tetapi jawabannya mungkin berbeda jika himpunan nilai dimodifikasi secara dinamis, atau perlu berkembang seiring waktu. Dalam sebagian besar bahasa, mengubah
enum
jenis (misalnya untuk menambah atau menghapus nilai) membutuhkan kompilasi ulang yang lengkap. (Misalnya, menghapus nilai enum di Java merusak kompatibilitas biner.) Dan hal yang sama berlaku untuk konstanta integer bernama.Dalam skenario seperti ini solusi lain mungkin diperlukan, dan menggunakan string adalah salah satu opsi. (Dan Anda bisa menggabungkan string literal dan konstanta bernama ... jika skenario memerlukan inti tetap dengan ekstensi dinamis.)
Jika Anda menerapkan di Jawa,
character.direction == "left"
praktik buruk karena alasan lain. Anda sebaiknya tidak menggunakan==
untuk membandingkan string, karena ini menguji identitas objek daripada kesetaraan string. (Ini akan berhasil jika Anda bisa menjamin bahwa semua instance dari"left"
string telah diinternir, tetapi itu membutuhkan analisis seluruh aplikasi.)sumber
String
untuk mewakili arah akan membuat hampir nol perbedaan dengan jumlah pekerjaan yang terlibat untuk melakukan perubahan. Pendekatan yang lebih masuk akal adalah mengasumsikan bahwa jumlah arah tidak akan berubah, dan menyadari bahwa Anda akan memiliki banyak pekerjaan untuk dilakukan dengan cara lain jika aturan permainan berubah secara mendasar.Seperti yang disarankan, Anda harus menggunakan Enums. Namun, hanya menggunakan Enum sebagai pengganti Strigns tidak cukup IMHO. Dalam contoh part Anda, kecepatan pemain seharusnya menjadi vektor melalui fisika:
Vektor ini kemudian harus digunakan untuk memperbarui posisi pemain setiap centang.
Anda kemudian dapat menggabungkannya dengan enum untuk keterbacaan yang lebih tinggi:
sumber