Sintaksis scala memiliki banyak simbol. Karena nama-nama seperti ini sulit ditemukan menggunakan mesin pencari, daftar yang lengkap akan sangat membantu.
Apa saja simbol dalam Scala, dan apa yang masing-masing lakukan?
Secara khusus, saya ingin tahu tentang ->
, ||=
, ++=
, <=
, _._
, ::
, dan :+=
.
Jawaban:
Saya membagi operator, untuk tujuan pengajaran, menjadi empat kategori :
Untungnya, sebagian besar kategori terwakili dalam pertanyaan:
Arti yang tepat dari sebagian besar metode ini tergantung pada kelas yang mendefinisikannya. Misalnya,
<=
padaInt
berarti "kurang dari atau sama dengan" . Yang pertama->
,, saya akan berikan contoh di bawah ini.::
mungkin adalah metode yang didefinisikanList
(meskipun itu bisa menjadi objek dengan nama yang sama), dan:+=
mungkin metode yang didefinisikan pada berbagaiBuffer
kelas.Jadi, mari kita lihat.
Kata kunci / simbol yang dicadangkan
Ada beberapa simbol dalam Scala yang spesial. Dua di antaranya dianggap kata kunci yang tepat, sementara yang lain hanya "dipesan". Mereka:
Ini semua adalah bagian dari bahasa , dan, dengan demikian, dapat ditemukan dalam teks apa pun yang menggambarkan bahasa dengan benar, seperti Spesifikasi Scala (PDF) itu sendiri.
Yang terakhir, garis bawah, layak mendapat deskripsi khusus, karena sangat banyak digunakan, dan memiliki banyak arti berbeda. Berikut ini contohnya:
Tapi saya mungkin lupa arti lain.
Metode yang diimpor secara otomatis
Jadi, jika Anda tidak menemukan simbol yang Anda cari dalam daftar di atas, maka itu harus berupa metode, atau bagian dari satu. Tetapi, seringkali, Anda akan melihat beberapa simbol dan dokumentasi untuk kelas tidak akan memiliki metode itu. Ketika ini terjadi, apakah Anda melihat komposisi dari satu metode atau lebih dengan sesuatu yang lain, atau metode tersebut telah diimpor ke dalam ruang lingkup, atau tersedia melalui konversi implisit yang diimpor.
Ini masih dapat ditemukan di ScalaDoc : Anda hanya harus tahu di mana mencarinya. Atau, gagal itu, lihat indeks (saat ini rusak pada 2.9.1, tetapi tersedia pada malam hari).
Setiap kode Scala memiliki tiga impor otomatis:
Dua yang pertama hanya menyediakan kelas dan objek tunggal. Yang ketiga berisi semua konversi implisit dan metode yang diimpor, karena
Predef
merupakan objek itu sendiri.Melihat ke dalam
Predef
dengan cepat menunjukkan beberapa simbol:Simbol lain apa pun akan disediakan melalui konversi tersirat . Lihat saja metode yang ditandai dengan
implicit
yang menerima, sebagai parameter, objek bertipe yang menerima metode. Sebagai contoh:Dalam kasus di atas,
->
didefinisikan dalam kelasArrowAssoc
melalui metodeany2ArrowAssoc
yang mengambil objek bertipeA
, di manaA
parameter tipe tidak terikat ke metode yang sama.Metode umum
Jadi, banyak simbol hanyalah metode di kelas. Misalnya, jika Anda melakukannya
Anda akan menemukan metode ini
++
tepat di ScalaDoc untuk Daftar . Namun, ada satu konvensi yang harus Anda waspadai saat mencari metode. Metode yang berakhir dengan titik dua (:
) mengikat ke kanan, bukan ke kiri. Dengan kata lain, sementara pemanggilan metode di atas setara dengan:Sebaliknya
1 :: List(2, 3)
, jika saya memiliki , itu akan setara dengan:Jadi, Anda perlu melihat jenis yang ditemukan di sebelah kanan ketika mencari metode yang berakhir dengan titik dua. Pertimbangkan, misalnya:
Metode pertama (
+:
) mengikat ke kanan, dan ditemukan padaList
. Metode kedua (:+
) hanyalah metode normal, dan mengikat ke kiri - lagi, padaList
.Gula / komposisi sintaksis
Jadi, inilah beberapa gula sintaksis yang mungkin menyembunyikan metode:
Yang terakhir menarik, karena metode simbolis apa pun dapat digabungkan untuk membentuk metode penugasan seperti itu.
Dan, tentu saja, ada berbagai kombinasi yang dapat muncul dalam kode:
sumber
val c = ex(2)
alih-alihval ex(c) = 2
?val ex(c) = 2
.Satu perbedaan (baik, IMO) antara Scala dan bahasa lain adalah ia memungkinkan Anda memberi nama metode Anda dengan hampir semua karakter.
Apa yang Anda sebutkan bukanlah "tanda baca" tetapi metode sederhana dan sederhana, dan dengan demikian perilakunya bervariasi dari satu objek ke objek lainnya (meskipun ada beberapa konvensi).
Misalnya, periksa dokumentasi Scaladoc untuk Daftar , dan Anda akan melihat beberapa metode yang Anda sebutkan di sini.
Beberapa hal yang perlu diingat:
Sebagian besar
A operator+equal B
kombinasi waktu diterjemahkan menjadiA = A operator B
, seperti dalam||=
atau++=
contoh.Metode yang berakhir dengan
:
asosiatif benar, ini berarti ituA :: B
sebenarnyaB.::(A)
.Anda akan menemukan sebagian besar jawaban dengan menjelajahi dokumentasi Scala. Menyimpan referensi di sini akan menggandakan upaya, dan itu akan jatuh dengan cepat :)
sumber
Anda dapat mengelompokkannya terlebih dahulu sesuai dengan beberapa kriteria. Dalam posting ini saya hanya akan menjelaskan karakter garis bawah dan panah kanan.
_._
berisi titik. Periode di Scala selalu menunjukkan pemanggilan metode . Jadi kiri periode Anda memiliki penerima, dan kanannya pesan (nama metode). Sekarang_
adalah simbol khusus di Scala. Ada beberapa posting tentang itu, misalnya entri blog ini semua menggunakan kasus. Ini adalah jalan pintas fungsi anonim , yang merupakan jalan pintas untuk fungsi yang mengambil satu argumen dan memanggil metode_
di atasnya. Sekarang_
bukan metode yang valid, jadi pasti Anda melihat_._1
atau sesuatu yang serupa, yaitu, memanggil metode_._1
pada argumen fungsi._1
to_22
adalah metode tuple yang mengekstraksi elemen tertentu dari tuple. Contoh:Sekarang mari kita asumsikan sebuah use case untuk shortcut aplikasi fungsi. Diberi peta yang memetakan bilangan bulat ke string:
Wooop, sudah ada tanda baca aneh lainnya. Karakter tanda hubung dan lebih besar dari, yang menyerupai panah kanan , adalah operator yang menghasilkan a
Tuple2
. Jadi tidak ada perbedaan dalam hasil penulisan baik(1, "Eins")
atau1 -> "Eins"
, hanya bahwa yang terakhir lebih mudah dibaca, terutama dalam daftar tupel seperti contoh peta. Ini->
bukan sihir, itu, seperti beberapa operator lain, tersedia karena Anda memiliki semua konversi implisit dalam objekscala.Predef
dalam ruang lingkup. Konversi yang terjadi di sini adalahDimana
ArrowAssoc
memiliki->
metode yang menciptakanTuple2
. Dengan demikian1 -> "Eins"
panggilan yang sebenarnyaPredef.any2ArrowAssoc(1).->("Eins")
. Baik. Sekarang kembali ke pertanyaan awal dengan karakter garis bawah:Garis bawah di sini mempersingkat kode setara berikut:
Perhatikan bahwa
map
metode Peta lewat dalam tupel kunci dan nilai ke argumen fungsi. Karena kami hanya tertarik pada nilai-nilai (string), kami mengekstraknya dengan_2
metode pada tuple.sumber
->
metode ini tetapi kalimat Anda "Jadi tidak ada perbedaan dalam hasil penulisan baik(1, "Eins")
atau1 -> "Eins"
" membantu saya memahami sintaks dan penggunaannya.Sebagai tambahan untuk jawaban brilian Daniel dan 0__, saya harus mengatakan bahwa Scala memahami analog Unicode untuk beberapa simbol, jadi alih-alih
orang dapat menulis
sumber
Mengenai
::
ada entri Stackoverflow lain yang mencakup::
kasus ini. Singkatnya, ini digunakan untuk membangunLists
dengan ' menyetujui ' elemen kepala dan daftar ekor. Ini adalah kelas yang mewakili daftar yang diikuti dan yang dapat digunakan sebagai ekstraktor, tetapi paling umum itu adalah metode pada daftar. Seperti yang Pablo Fernandez tunjukkan, karena berakhir di titik dua, itu adalah asosiatif yang benar , artinya penerima panggilan metode ada di kanan, dan argumen di sebelah kiri operator. Dengan begitu Anda dapat mengekspresikan konsing secara elegan sebagai menambahkan elemen kepala baru ke daftar yang ada:Ini setara dengan
Penggunaan sebagai objek extractor adalah sebagai berikut:
Ini terlihat seperti operator di sini, tetapi ini sebenarnya hanyalah cara penulisan (yang lebih mudah dibaca)
Anda dapat membaca lebih lanjut tentang ekstraktor di pos ini .
sumber
<=
sama seperti Anda akan "membacanya": 'kurang dari atau sama dengan'. Jadi operator matematika, dalam daftar<
(kurang dari?),>
(Lebih besar dari?),==
(!=
Sama dengan?), (Tidak sama?),<=
(Kurang dari atau sama?), Dan>=
(lebih besar dari atau sama?).Ini tidak harus bingung dengan
=>
yang merupakan jenis panah kanan ganda , yang digunakan untuk memisahkan daftar argumen dari tubuh fungsi dan untuk memisahkan kondisi pengujian dalam pencocokan pola (case
blok) dari tubuh yang dieksekusi ketika pertandingan terjadi . Anda dapat melihat contoh ini di dua jawaban saya sebelumnya. Pertama, fungsinya menggunakan:yang sudah disingkat jenis dihilangkan. Fungsi follow adalah
dan penggunaan pencocokan pola:
sumber
Saya menganggap IDE modern sangat penting untuk memahami proyek scala besar. Karena operator ini juga metode, dalam ide intellij saya hanya mengontrol klik atau kontrol-b ke dalam definisi.
Anda dapat mengontrol klik kanan ke operator kontra (: :) dan berakhir di scala javadoc mengatakan "Menambahkan elemen di awal daftar ini." Dalam operator yang ditentukan pengguna, ini menjadi lebih kritis, karena mereka dapat didefinisikan dalam implisit yang sulit ditemukan ... IDE Anda tahu di mana implisit didefinisikan.
sumber
Hanya menambah jawaban bagus lainnya. Scala menawarkan dua operator simbolik yang sering dikritik,
/:
(foldLeft
) dan:\
(foldRight
) operator, yang pertama adalah asosiatif-kanan. Jadi tiga pernyataan berikut ini setara:Seperti tiga ini:
sumber
Scala mewarisi sebagian besar operator aritmatika Jawa . Ini termasuk bitwise-atau
|
(karakter pipa tunggal), bitwise-dan&
, bitwise-eksklusif-atau^
, serta logis (boolean) atau||
(dua karakter pipa) dan logis-dan&&
. Menariknya, Anda dapat menggunakan operator karakter tunggalboolean
, sehingga operator logis java'r benar-benar berlebihan:Seperti yang ditunjukkan di pos lain, panggilan yang berakhir dengan tanda sama dengan
=
, diselesaikan (jika metode dengan nama itu tidak ada!) Dengan penugasan kembali:'Pemeriksaan ulang' ini memungkinkan, untuk dengan mudah menukar yang dapat diubah untuk koleksi yang tidak berubah:
sumber
true | { println( "Icke" ); true }
⇒ dicetak!true || { println( "Icke" ); true }
⇒ tidak mencetak!