SORU
27 Mart 2010, CUMARTESİ


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
27 Mart 2010, CUMARTESİ


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.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • CNET

    CNET

    5 Mayıs 2006
  • cyriak

    cyriak

    29 Mart 2006
  • theavettbrothers

    theavettbrot

    9 ŞUBAT 2007