Tanda plus +
digunakan untuk penambahan dan untuk penggabungan string, tetapi pasangannya: tanda minus -
, umumnya tidak terlihat untuk memotong string atau kasus lain selain pengurangan. Apa yang bisa menjadi alasan atau batasan untuk itu?
Pertimbangkan contoh berikut dalam JavaScript:
var a = "abcdefg";
var b = "efg";
a-b == NaN
// but
a+b == "abcdefgefg"
coding-standards
history
operators
overload
Digvijay Yadav
sumber
sumber
+
operator biner kelebihan beban dengan dua arti yang sama sekali tidak terkait "penambahan numerik" dan "penggabungan string". Untungnya, beberapa bahasa menyediakan operator gabungan yang terpisah seperti.
(Perl5, PHP),~
(Perl6),&
(VB),++
(Haskell), ...->
(pikirkan akses anggota dereferencing dalam C, karena panggilan metode virtual harus melibatkan tipuan seperti pointer). Tidak ada hukum desain bahasa yang mengharuskan pemanggilan metode / akses anggota untuk menggunakan.
operator, meskipun itu adalah konvensi yang semakin umum. Tahukah Anda bahwa Smalltalk tidak memiliki operator panggilan metode? Penjajaran sederhanaobject method
sudah cukup.Jawaban:
Singkatnya, tidak ada operasi pengurangan yang sangat berguna pada string yang orang ingin tuliskan algoritmanya.
The
+
Operator umumnya menunjukkan operasi aditif monoid , yaitu, operasi asosiatif dengan elemen identitas:Masuk akal untuk menggunakan operator ini untuk hal-hal seperti penambahan integer, penggabungan string, dan penyatuan gabungan karena mereka semua memiliki struktur aljabar yang sama:
Dan kita dapat menggunakannya untuk menulis algoritme praktis seperti
concat
fungsi yang bekerja pada urutan hal-hal yang “dapat digabungkan”, misalnya:Ketika pengurangan
-
terlibat, Anda biasanya berbicara tentang struktur grup , yang menambahkan −A terbalik untuk setiap elemen A, sehingga:Dan sementara ini masuk akal untuk hal-hal seperti integer dan pengurangan floating-point, atau bahkan perbedaan, itu tidak masuk akal untuk string dan daftar. Apa kebalikannya
"foo"
?Ada struktur yang disebut monoid pembatalan , yang tidak memiliki invers, tetapi memiliki properti pembatalan , sehingga:
Ini adalah struktur yang Anda gambarkan, di mana
"ab" - "b" == "a"
, tetapi"ab" - "c"
tidak didefinisikan. Hanya saja kami tidak memiliki banyak algoritma yang bermanfaat yang menggunakan struktur ini. Saya kira jika Anda menganggap Rangkaian sebagai serialisasi, maka pengurangan dapat digunakan untuk beberapa jenis parsing.sumber
+
operasi juga komutatif untuk angka, yaituA+B == B+A
, yang membuatnya menjadi kandidat yang buruk untuk penggabungan string. Ini, ditambah operator yang didahulukan dari operator yang membingungkan menjadikan+
penggabungan string sebagai kesalahan historis. Namun, memang benar bahwa menggunakan-
operasi string apa pun membuat segalanya lebih buruk ....
dari Perl; ada~
di Perl6, mungkin yang lain..text.gz.text
...Karena rangkaian dari dua string yang valid selalu merupakan operasi yang valid, tetapi yang sebaliknya tidak benar.
Apa yang seharusnya
a - b
ada di sini? Benar-benar tidak ada cara yang baik untuk menjawab pertanyaan itu, karena pertanyaan itu sendiri tidak valid.sumber
5 + False
seharusnya kesalahan , karena angka bukan boolean dan boolean bukan angka.(a+b)-b = a
(mudah-mudahan!), Tetapi(a-b)+b
kadang-kadanga
, kadanga+b
- kadang tergantung pada apakahb
substringa
atau tidak? Kegilaan apa ini?Karena
-
operator untuk manipulasi string tidak memiliki cukup "kohesi semantik." Operator hanya boleh kelebihan beban ketika benar-benar jelas apa kelebihan beban dengan operannya, dan pengurangan string tidak memenuhi bilah itu.Akibatnya, panggilan metode lebih disukai:
Dalam bahasa C #, kami menggunakan
+
untuk rangkaian string karena bentukdari pada
nyaman dan bisa dibilang lebih mudah dibaca, meskipun pemanggilan fungsi mungkin lebih "benar," dari sudut pandang semantik.
The
+
operator dapat benar-benar hanya berarti satu hal dalam konteks ini. Hal ini tidak berlaku untuk-
, karena gagasan mengurangkan string adalah ambigu (fungsi panggilanReplace(source, oldValue, newValue)
dengan""
sebagainewValue
parameter menghapus semua keraguan, dan fungsi tersebut dapat digunakan untuk mengubah substring, bukan hanya menghapusnya).Masalahnya, tentu saja, adalah bahwa operator kelebihan beban tergantung pada jenis yang diteruskan ke operator, dan jika Anda melewati string di mana nomor seharusnya, Anda mungkin mendapatkan hasil yang tidak Anda harapkan. Selain itu, untuk banyak rangkaian (yaitu dalam satu lingkaran), suatu
StringBuilder
objek lebih disukai, karena setiap penggunaan+
menciptakan string baru, dan kinerja dapat menderita. Jadi+
operator bahkan tidak sesuai dalam semua konteks.Ada kelebihan operator yang memiliki keterpaduan semantik yang lebih baik daripada yang dilakukan
+
operator untuk penggabungan string. Inilah satu yang menambahkan dua bilangan kompleks:sumber
Bahasa Groovy memungkinkan
-
:pengembalian:
Dan:
pengembalian:
Dan:
pengembalian:
sumber
('ABABABABA' + 'B') - 'B'
mendekati nilai awal'ABABABABA'
.(A + B) - A == B
untuk setiap A dan B. Dapatkah saya menyebutnya pengurangan kiri?++
untuk penggabungan. Ini berfungsi pada daftar apa pun dan string hanyalah daftar karakter. Itu juga memiliki\\
, yang menghilangkan kejadian pertama dari setiap elemen dalam argumen kanan dari argumen kiri.Tanda plus mungkin secara kontekstual masuk akal dalam banyak kasus, tetapi contoh tandingan (mungkin pengecualian yang membuktikan aturan) dalam Python adalah objek yang ditetapkan, yang menyediakan
-
tetapi tidak+
:Tidak masuk akal untuk menggunakan
+
tanda itu karena niatnya bisa ambigu - apakah itu berarti mengatur persimpangan atau persatuan? Alih-alih, ini digunakan|
untuk gabungan dan&
untuk persimpangan:sumber
set('abc') ^ set('bcd')
kembaliset(['a', 'd'])
, jika Anda bertanya tentang perbedaan simetris."
-
" digunakan dalam beberapa kata majemuk (misalnya, "di tempat") untuk menggabungkan bagian-bagian yang berbeda ke dalam kata yang sama. Mengapa kita tidak menggunakan "-
" untuk menggabungkan berbagai string dalam bahasa pemrograman? Saya pikir itu akan masuk akal! Persetan dengan+
omong kosong ini !Namun, mari kita coba melihat ini dari sudut yang lebih abstrak.
Bagaimana Anda mendefinisikan aljabar string? Operasi apa yang akan Anda miliki, dan hukum apa yang berlaku bagi mereka? Akan seperti apa hubungan mereka?
Ingat, mungkin sama sekali tidak ada ambiguitas! Setiap kasus yang mungkin harus didefinisikan dengan baik, bahkan jika itu berarti mengatakan tidak mungkin untuk melakukan ini! Semakin kecil aljabar Anda, semakin mudah hal ini dilakukan.
Misalnya, apa sebenarnya arti menambahkan atau mengurangi dua string?
Jika Anda menambahkan dua string (misalnya, biarkan
a = "aa"
danb = "bb"
), apakah Anda akan mendapatkanaabb
hasila + b
?Bagaimana dengan
b + a
? Apakah itu akan terjadibbaa
? Mengapa tidakaabb
? Apa yang terjadi jika Anda mengurangiaa
hasil penambahan Anda? Apakah string Anda memiliki konsep jumlah negatifaa
di dalamnya?Sekarang kembali ke awal jawaban ini dan gantikan
spaceshuttle
string. Untuk menggeneralisasi, mengapa operasi apa pun didefinisikan atau tidak didefinisikan untuk jenis apa pun?Maksud saya adalah, bahwa tidak ada yang menghentikan Anda dari membuat aljabar untuk apa pun. Mungkin sulit untuk menemukan operasi yang berarti, atau bahkan operasi yang bermanfaat untuknya.
Sebagai gantinya, penggabungan adalah satu-satunya yang masuk akal yang pernah saya temui. Tidak masalah simbol apa yang digunakan untuk mewakili operasi.
sumber
'xy' * 3 == 'xyxyxy'
?