Saya membaca Fungsi Scala (bagian dari tur Scala lainnya ). Dalam pos itu ia menyatakan:
Metode dan fungsi bukan hal yang sama
Tetapi dia tidak menjelaskan apa-apa tentang itu. Apa yang dia katakan?
Saya membaca Fungsi Scala (bagian dari tur Scala lainnya ). Dalam pos itu ia menyatakan:
Metode dan fungsi bukan hal yang sama
Tetapi dia tidak menjelaskan apa-apa tentang itu. Apa yang dia katakan?
Jawaban:
Jim telah membahas hal ini cukup banyak di posting blognya , tapi saya memposting briefing di sini untuk referensi.
Pertama, mari kita lihat apa yang dikatakan Spesifikasi Scala. Bab 3 (tipe) memberi tahu kita tentang Tipe Fungsi (3.2.9) dan Tipe Metode (3.3.1). Bab 4 (deklarasi dasar) berbicara tentang Deklarasi Nilai dan Definisi (4.1), Deklarasi dan Definisi Variabel (4.2) dan Deklarasi dan Definisi Fungsi (4.6). Bab 6 (ekspresi) berbicara tentang Fungsi Anonim (6.23) dan Nilai Metode (6.7). Anehnya, nilai-nilai fungsi dibicarakan satu kali pada 3.2.9, dan tidak ada tempat lain.
Sebuah Fungsi Type adalah (kira-kira) jenis bentuk (T1, ..., Tn) => U , yang merupakan singkatan untuk sifat
FunctionN
di perpustakaan standar. Fungsi dan Metode Anonim Nilai memiliki tipe fungsi, dan tipe fungsi dapat digunakan sebagai bagian dari nilai, deklarasi dan definisi variabel dan fungsi. Bahkan, itu bisa menjadi bagian dari tipe metode.Sebuah Metode Type adalah jenis non-nilai . Itu berarti tidak ada nilai - tidak ada objek, tidak ada contoh - dengan tipe metode. Seperti disebutkan di atas, Nilai Metode sebenarnya memiliki Tipe Fungsi . Tipe metode adalah
def
deklarasi - segala sesuatu tentangdef
kecuali tubuhnya.Nilai Deklarasi dan Definisi dan Deklarasi Variabel dan Definisi yang
val
danvar
deklarasi, termasuk kedua jenis dan nilai - yang dapat, masing-masing, Fungsi Jenis dan Fungsi Anonymous atau Nilai Metode . Perhatikan bahwa, pada JVM, ini (nilai metode) diimplementasikan dengan apa yang disebut Java "metode".Sebuah Fungsi Deklarasi adalah
def
deklarasi, termasuk jenis dan tubuh . Bagian tipe adalah Tipe Metode, dan tubuh adalah ekspresi atau blok . Ini juga diimplementasikan pada JVM dengan apa yang disebut Java "metode".Akhirnya, Fungsi Anonim adalah turunan dari Tipe Fungsi (yaitu, turunan dari sifat tersebut
FunctionN
), dan Nilai Metode adalah hal yang sama! Perbedaannya adalah bahwa Nilai Metode dibuat dari metode, baik dengan postfixing garis bawah (m _
adalah nilai metode yang sesuai dengan "deklarasi fungsi" (def
)m
), atau dengan proses yang disebut ekspansi eta , yang seperti pemeran otomatis dari metode berfungsi.Itulah yang dikatakan oleh spesifikasi, jadi izinkan saya menjelaskannya : kita tidak menggunakan terminologi itu! Ini menyebabkan terlalu banyak kebingungan antara apa yang disebut "deklarasi fungsi" , yang merupakan bagian dari program (bab 4 - deklarasi dasar) dan "fungsi anonim" , yang merupakan ekspresi, dan "tipe fungsi" , yaitu, baik tipe - sifat.
Terminologi di bawah ini, dan digunakan oleh programmer Scala yang berpengalaman, membuat satu perubahan dari terminologi spesifikasi: alih-alih mengatakan deklarasi fungsi , kami mengatakan metode . Atau bahkan deklarasi metode. Lebih lanjut, kami mencatat bahwa deklarasi nilai dan deklarasi variabel juga merupakan metode untuk tujuan praktis.
Jadi, mengingat perubahan terminologi di atas, inilah penjelasan praktis tentang perbedaan tersebut.
Sebuah fungsi adalah obyek yang termasuk salah satu
FunctionX
ciri-ciri, sepertiFunction0
,Function1
,Function2
, dll mungkin termasukPartialFunction
juga, yang benar-benar meluasFunction1
.Mari kita lihat jenis tanda tangan untuk salah satu ciri berikut:
Ciri ini memiliki satu metode abstrak (ia memiliki beberapa metode konkret juga):
Dan itu memberi tahu kita semua yang perlu diketahui tentang hal itu. Sebuah fungsi memiliki
apply
metode yang menerima N parameter jenis T1 , T2 , ..., TN , dan kembali sesuatu dari jenisR
. Ini bertentangan pada parameter yang diterimanya, dan ko-varian pada hasilnya.Varians itu berarti bahwa a
Function1[Seq[T], String]
adalah subtipe dariFunction1[List[T], AnyRef]
. Menjadi subtipe berarti dapat digunakan sebagai pengganti . Orang dapat dengan mudah melihat bahwa jika saya akan meneleponf(List(1, 2, 3))
dan mengharapkanAnyRef
kembali, salah satu dari dua jenis di atas akan berfungsi.Sekarang, apa kesamaan metode dan fungsi? Nah, jika
f
fungsi danm
metode lokal untuk ruang lingkup, maka keduanya bisa disebut seperti ini:Panggilan-panggilan ini sebenarnya berbeda, karena yang pertama hanyalah gula sintaksis. Scala mengembangkannya ke:
Yang, tentu saja, adalah pemanggilan metode pada objek
f
. Fungsinya juga memiliki gula sintaksis lainnya untuk keuntungannya: fungsi literal (sebenarnya dua di antaranya) dan(T1, T2) => R
ketik tanda tangan. Sebagai contoh:Kesamaan lain antara metode dan fungsi adalah bahwa yang pertama dapat dengan mudah dikonversi menjadi yang terakhir:
Scala akan memperluas itu , dengan asumsi
m
tipe(List[Int])AnyRef
menjadi (Scala 2.7):Pada Scala 2.8, ini sebenarnya menggunakan
AbstractFunction1
kelas untuk mengurangi ukuran kelas.Perhatikan bahwa seseorang tidak dapat mengonversi sebaliknya - dari suatu fungsi ke metode.
Metode, bagaimanapun, memiliki satu keuntungan besar (baik, dua - mereka bisa sedikit lebih cepat): mereka dapat menerima parameter tipe . Misalnya, sementara di
f
atas dapat menentukan jenisList
yang diterimanya (List[Int]
dalam contoh),m
dapat parameterisasi:Saya pikir ini cukup banyak mencakup segalanya, tetapi saya akan dengan senang hati melengkapi ini dengan jawaban atas pertanyaan yang mungkin tersisa.
sumber
val f = m
oleh kompiler seperti yangval f = new AnyRef with Function1[List[Int], AnyRef] { def apply(x$1: List[Int]) = this.m(x$1) }
Anda harus tunjukkan bahwa dithis
dalamapply
metode tidak merujuk keAnyRef
objek, tetapi ke objek yang metodenyaval f = m _
dievaluasi ( luarthis
, jadi bisa dikatakan ), karenathis
berada di antara nilai-nilai yang ditangkap oleh penutupan (seperti misalnyareturn
seperti yang ditunjukkan di bawah).Satu perbedaan praktis besar antara metode dan fungsi adalah apa
return
artinya.return
hanya pernah kembali dari suatu metode. Sebagai contoh:Kembali dari fungsi yang didefinisikan dalam suatu metode menghasilkan pengembalian non-lokal:
Sedangkan kembali dari metode lokal hanya kembali dari metode itu.
sumber
for (a <- List(1, 2, 3)) { return ... }
? Itu akan ditutup untuk penutupan.return
mengembalikan nilai dari fungsi, dan beberapa bentukescape
ataubreak
ataucontinue
untuk kembali dari metode.Pemrograman dalam Scala Edisi Kedua. Martin Odersky - Lex Spoon - Bill Venners
sumber
Katakanlah Anda memiliki Daftar
Tentukan Metode
Tentukan Fungsi
Metode Menerima Argumen
Mendefinisikan Fungsi dengan val
Argumen untuk fungsi adalah Opsional
Argumen untuk Metode adalah Wajib
Periksa Tutorial berikut yang menjelaskan lewat perbedaan lain dengan contoh-contoh seperti contoh lain dari diff dengan Fungsi Metode Vs, Menggunakan fungsi sebagai Variabel, membuat fungsi yang mengembalikan fungsi
sumber
Fungsi tidak mendukung standar parameter. Metode lakukan. Konversi dari metode ke fungsi kehilangan default parameter. (Scala 2.8.1)
sumber
Ada artikel bagus di sini dari mana sebagian besar deskripsi saya diambil. Hanya perbandingan singkat dari Fungsi dan Metode mengenai pemahaman saya. Semoga ini bisa membantu:
Fungsi : Mereka pada dasarnya adalah objek. Lebih tepatnya, fungsi adalah objek dengan metode yang berlaku; Oleh karena itu, mereka sedikit lebih lambat daripada metode karena overhead mereka. Ini mirip dengan metode statis dalam arti bahwa mereka tidak tergantung pada objek yang akan dipanggil. Contoh sederhana dari suatu fungsi adalah seperti di bawah ini:
Baris di atas tidak lain adalah menugaskan satu objek ke objek lain seperti object1 = object2. Sebenarnya object2 dalam contoh kita adalah fungsi anonim dan sisi kiri mendapatkan jenis objek karena itu. Karena itu, sekarang f1 adalah objek (Fungsi). Fungsi anonim sebenarnya adalah instance dari Function1 [Int, Int] yang berarti fungsi dengan 1 parameter tipe Int dan mengembalikan nilai tipe Int. Memanggil f1 tanpa argumen akan memberi kita tanda tangan dari fungsi anonim (Int => Int =)
Metode : Mereka bukan objek tetapi ditugaskan ke instance kelas, yaitu objek. Persis sama dengan metode di java atau fungsi anggota dalam c ++ (seperti yang ditunjukkan oleh Raffi Khatchadourian dalam komentar untuk pertanyaan ini ) dan lain-lain. Contoh sederhana dari sebuah metode sama seperti di bawah ini:
Baris di atas bukanlah penetapan nilai sederhana tetapi definisi metode. Ketika Anda memanggil metode ini dengan nilai 2 seperti baris kedua, x diganti dengan 2 dan hasilnya akan dihitung dan Anda mendapatkan 4 sebagai output. Di sini Anda akan mendapatkan kesalahan jika cukup menulis m1 karena ini adalah metode dan perlu nilai input. Dengan menggunakan _ Anda dapat menetapkan metode ke fungsi seperti di bawah ini:
sumber
Ini adalah posting yang bagus dari Rob Norris yang menjelaskan perbedaannya, ini adalah TL; DR
dengan definisi berikut:
Singkatnya ( ekstrak dari blog ):
Ketika kita mendefinisikan suatu metode, kita melihat bahwa kita tidak dapat menetapkannya ke a
val
.Perhatikan juga jenis dari
add1
yang tidak terlihat normal; Anda tidak dapat mendeklarasikan variabel tipe(n: Int)Int
. Metode bukanlah nilai.Namun, dengan menambahkan operator postfix-ekspansi (η diucapkan “eta”), kita dapat mengubah metode menjadi nilai fungsi. Perhatikan jenis
f
.Efeknya
_
adalah untuk melakukan yang setara dari yang berikut: kami membangun sebuahFunction1
instance yang mendelegasikan ke metode kami.sumber
Dalam Scala 2.13, tidak seperti fungsi, metode dapat mengambil / kembali
Namun, pembatasan ini diangkat dalam dotty (Scala 3) oleh tipe fungsi Polymorphic # 4672 , misalnya, dotty versi 0.23.0-RC1 memungkinkan sintaks berikut
Ketikkan parameter
Parameter implisit ( parameter konteks )
Jenis tergantung
Untuk contoh lebih lanjut, lihat tes / jalankan / polymorphic-functions.scala
sumber
Secara praktis, seorang programmer Scala hanya perlu mengetahui tiga aturan berikut untuk menggunakan fungsi dan metode dengan benar:
def
dan fungsi literal yang didefinisikan oleh=>
adalah fungsi. Ini didefinisikan di halaman 143, Bab 8 dalam buku Programming in Scala, edisi ke-4.someNumber.foreach(println)
Setelah empat edisi Pemrograman dalam Scala, masih menjadi masalah bagi orang untuk membedakan dua konsep penting: fungsi dan nilai fungsi karena semua edisi tidak memberikan penjelasan yang jelas. Spesifikasi bahasa terlalu rumit. Saya menemukan aturan di atas sederhana dan akurat.
sumber