Apakah ada perbedaan di antara keduanya :::
dan ++
untuk daftar gabungan di Scala?
scala> List(1,2,3) ++ List(4,5)
res0: List[Int] = List(1, 2, 3, 4, 5)
scala> List(1,2,3) ::: List(4,5)
res1: List[Int] = List(1, 2, 3, 4, 5)
scala> res0 == res1
res2: Boolean = true
Dari dokumentasi sepertinya ++
lebih umum sedangkan :::
yaituList
spesifik. Apakah yang terakhir disediakan karena digunakan dalam bahasa fungsional lainnya?
list
scala
concatenation
Luigi Plinge
sumber
sumber
:::
merupakan operator awalan seperti semua metode yang dimulai dengan:
Jawaban:
Warisan. Daftar awalnya didefinisikan sebagai fungsional-mencari bahasa:
Tentu saja, Scala mengembangkan koleksi lain, secara ad-hoc. Ketika 2,8 keluar, koleksi yang dirancang ulang untuk digunakan kembali kode maksimum dan API konsisten, sehingga Anda dapat menggunakan
++
untuk menggabungkan setiap dua koleksi - dan bahkan iterator. Daftar, bagaimanapun, harus menjaga operator aslinya, selain dari satu atau dua yang sudah usang.sumber
:::
mendukung++
sekarang? Juga gunakan+:
bukan::
?::
berguna karena pencocokan pola (lihat Daniel contoh kedua). Anda tidak dapat melakukannya dengan+:
List
alih-alihSeq
, Anda sebaiknya menggunakanList
metode idiomatik . Di sisi lain, itu akan membuat lebih sulit untuk berubah ke tipe lain, jika Anda ingin melakukannya.::
dan:::
) dan operasi yang lebih umum yang umum untuk koleksi lainnya. Saya tidak akan membatalkan operasi dari bahasa.:+
dan mengekstraksi+:
objek.Selalu gunakan
:::
. Ada dua alasan: efisiensi dan keamanan tipe.Efisiensi
x ::: y ::: z
lebih cepat daripadax ++ y ++ z
, karena:::
asosiatif yang benar.x ::: y ::: z
diuraikan sebagaix ::: (y ::: z)
, yang secara algoritmik lebih cepat dari(x ::: y) ::: z
(yang terakhir membutuhkan O (| x |) langkah lebih lanjut).Ketik keamanan
Dengan
:::
Anda hanya dapat menggabungkan duaList
s. Dengan++
Anda dapat menambahkan koleksi apa pun keList
, yang mengerikan:++
juga mudah digabungkan dengan+
:sumber
x ::: y ::: z
sebaiknya diganti denganList(x, y, z).flatten
. pastebin.com/gkx7Hpadx
dany
(z
tidak pernah iterated dalam hal apapun sehingga tidak berpengaruh pada waktu berjalan, ini sebabnya lebih baik untuk menambahkan daftar panjang ke yang pendek, daripada sebaliknya) tetapi kompleksitas asimptotik tidak menceritakan keseluruhan cerita.x ::: (y ::: z)
mengulangy
dan menambahkanz
, lalu mengulangx
dan menambahkan hasily ::: z
.x
dany
keduanya diulang sekali.(x ::: y) ::: z
mengulangix
dan menambahkany
, lalu mengulangi hasil darix ::: y
dan menambahkanz
.y
masih diulang satu kali tetapix
diulang dua kali dalam kasus ini.:::
hanya bekerja dengan daftar, sementara++
dapat digunakan dengan traversable apa pun. Dalam implementasi saat ini (2.9.0),++
kembali aktif:::
jika argumennya juga aList
.sumber
Poin yang berbeda adalah kalimat pertama diurai sebagai:
Sedangkan contoh kedua diuraikan sebagai:
Jadi, jika Anda menggunakan makro, Anda harus berhati-hati.
Selain itu,
++
untuk dua daftar memanggil:::
tetapi dengan lebih banyak overhead karena meminta nilai implisit untuk memiliki pembangun dari Daftar ke Daftar. Tapi microbenchmarks tidak membuktikan sesuatu yang berguna dalam arti itu, saya kira kompiler mengoptimalkan panggilan tersebut.Tolok Ukur Mikro setelah pemanasan.
Seperti yang dikatakan Daniel C. Sobrai, Anda dapat menambahkan konten dari koleksi apa pun ke daftar menggunakan
++
, sedangkan dengan:::
Anda hanya dapat menggabungkan daftar.sumber