Scala yöntemi ve işlevi arasındaki fark
OkudumScala Functions(bir parçasıScala başka bir tur). O yazı şöyle diyordu:
Yöntemleri ve işlevleri aynı şey değildir
Ama bu konuda hiçbir şey anlatmadı. Ne demeye çalışıyor?
CEVAP
Jim bu oldukça fazla his blog post kaplı var ama burada bir brifing başvuru için post ediyorum.
İlk olarak, Scala Belirtimi bize ne olduğunu görelim. Bölüm 3 (türleri) bize anlatFonksiyon Türleri(3.2.9)Yöntem Türleri(3.3.1). Bölüm 4 (bildirileri) bahsederDeğer Bildirimi ve Tanımlar(4.1),Değişken tanımlaması ve Tanımları(4.2) veFonksiyonları Bildirimleri ve Tanımları(4.6). Bölüm 6 (ifade) konuşuyorAnonim Fonksiyonlar(6.23)Yöntem Değerleri(6.7). Merakla, fonksiyon değerleri başka yerde 3.2.9, ve hiç bir zaman konuşulur.
BirFonksiyon Yazın(kabaca) şeklinde bir tür(T1, ..., Tn) =>Ustandart kütüphanede özelliği FunctionN
bir kısaltma.Anonim FonksiyonlarveYöntem Değerleritür fonksiyon ve fonksiyon türleri değer, değişken ve fonksiyon bildirimleri ve tanımları bir parçası olarak kullanılabilir. Aslında, bu yöntem bir tür bir parçası olabilir.
BirYöntem Yazınbirolmayan bir değer yazın. Bu olduğu anlamına gelirhayırdeğer - hiçbir nesne, hiçbir örnek yöntemi bir tür. Yukarıda da belirtildiği gibi, birYöntem Değeraslında bir vardırFonksiyon Yazın. Yöntem bir tür def
Bildirgesini gövdesi hariç def
hakkında her şey.
Değer Bildirimleri ve TanımlarıveDeğişken Bildirimleri ve Tanımlarıval
var
bildirimleri, her ikisi detipi ve değeri- hangi, sırasıyla, olabilirFonksiyon Yazınveİsimsiz Fonksiyonlar veya Yöntemi Değerleri. , JVM, bu yöntem değerler) Java dediği ile uygulanan not "yöntem".
BirBildirim Fonksiyonubir def
beyan, dahil olmak üzereyazınvevücut. Yazın parçası Yöntem türüdür ve vücudun birifade veya bir blok. Bu da çağırır Java ile JVM üzerinde uygulanan "yöntem".
Son olarak, birAnonim İşlevbir örneğidirFonksiyon Yazın(yani, sürekli FunctionN
bir örneği), ve birYöntem Değeraynı şey! Ayrım bir Yöntem değerdir oluşturulan yöntem, her iki tarafından postfixing bir alt çizgi (m _
bir yöntem değeri karşılık gelen "işlev bildirimi" (def
) m
), veya bir süreci olarak adlandırılıreta-genişlemeçalışması için yöntem otomatik bir dökme gibi.
Bu görüşler ne olur, beni bu kadar ön koyalım:bu terminoloji kullanmayın!Sözde arasında çok fazla karışıklığa yol açar< . em ^"işlev bildirimi"programın bir parçası (Bölüm 4 -- bildirileri) olan ve ., >em ^"anonim işlev"bir ifadesi olan, ve ., >em^"" . fonksiyon türü olan , iyi bir tür bir özellik--.
Terminoloji aşağıda, Scala ve deneyimli programcılar tarafından kullanılan, belirtimi terimler: bir değişiklik yapardemek yerinebildirim fonksiyonubiz deriz kiyöntem. Hatta yöntem bildirimi. Ayrıca, unutmayındeğer bildirimlerivedeğişken tanımlamaaynı zamanda pratik amaçlar için. yöntemlerdir
Yani, bu terminolojiyi yukarıdaki değişimine bakarsak, burada ayrımın pratik bir açıklama.
BirişleviFunctionX
özellikleri, *19, *, Function2
, **20 gibi birini içeren bir nesnedir. Aslında Function1
uzanır PartialFunction
dahil de olabilir.
Hadi bu özelliklerin bir imza: bu tür bakın
trait Function2[-T1, -T2, R] extends AnyRef
Bu özellik, bir soyut yöntem (bir kaç somut yöntemler de vardır) vardır:
def apply(v1: T1, v2: T2): R
Bu konuda bilinmesi gereken her şeyi bize anlat. Birişlevivardır alan apply
bir yöntemNtür parametreleriT1,T2, ...,TNdöner tip bir şey R
. Aldığı parametreleri contra-varyant ve co-variant sonucu.
Farkı Function1[Seq[T], String]
Function1[List[T], AnyRef]
bir alt türü anlamına gelir. Bir alt tür olmak kullanılabilir anlamına geliryerine. Kolayca f(List(1, 2, 3))
arayıp AnyRef
bir döner edeceksem, iki tür üzerinde de çalışacak.
Şimdi, ne olurbenzerlikbir yöntem ve bir fonksiyon? f
bir fonksiyonudur ve m
bir yöntem kapsamında yerel ise o zaman hem bu gibi çağrılabilir:
val o1 = f(List(1, 2, 3))
val o2 = m(List(1, 2, 3))
Bu çağrılar ilk sadece sözdizimsel şeker çünkü aslında farklıdır. Scala genişletir:
val o1 = f.apply(List(1, 2, 3))
Tabii, bu bir yöntem f
nesne arayın. Fonksiyonlar da kendi avantajı için diğer sözdizimsel şeker var: fonksiyon rakamları (aslında, iki tanesi) ve (T1, T2) => R
tip imzalar. Örneğin:
val f = (l: List[Int]) => l mkString ""
val g: (AnyVal) => String = {
case i: Int => "Int"
case d: Double => "Double"
case o => "Other"
}
Bir yöntem ile işlev arasında bir benzerlik ilki kolay ikincisi dönüştürülebilir
val f = m _
Scala genişleyecektirbu, m
varsayarsak türüdür (List[Int])AnyRef
(2.7 Km):
val f = new AnyRef with Function1[List[Int], AnyRef] {
def apply(x$1: List[Int]) = this.m(x$1)
}
Scala üzerinde 2.8, aslında AbstractFunction1
bir sınıf sınıflar azaltmak için kullanır.
Tek bir yöntem, bir işlev-başka şekilde dönüştürebilirsiniz dikkat edin.
Ancak, büyük bir avantaj (iyi, biraz daha hızlı olabilir iki) yöntem: alabilirtür parametreleri. f
yukarıda mutlaka alır List
yazın ise örneğin, (List[Int]
örnekte), m
parametrelerle ifade edilebilir.:
def m[T](l: List[T]): String = l mkString ""
Bu hemen hemen her şeyi kapsıyor sanırım, ama kalan tüm sorulara cevap olan bu tamamlamak için mutlu olacağım.
Scala nesne ve sınıf arasındaki fark...
Scala'nın durumu, sınıf ve sınıf ...
Parantez ve parantez, Scala, resmi ara...
Scala artış var ve val tanımı arasında...
Scala içinde JavaConverters ve JavaCon...