2011-12-15 28 views
5

, :: sınıf (eksileri) tanımlanır sınıfta List yılındakitabında "Scala Programlama" Bölüm 22 yılında

final case class ::[T](hd: T, tl: List[T]) extends List[T] { 
    //... 
} 

:: yöntem olarak tanımlanır:

def ::[U >: T](x: U): List[U] = new scala.::(x, this) 

Neden newfinalcaseclass :: bir örneğini oluşturmak için gereklidir? Bu tamamen anlamsızlık için mi? Eğer sıradan bir sınıf ile yapabilirsiniz gibi otomatik olarak aynı şekilde, apply yöntem oluşturucu çağıran bir arkadaşı nesnesini almak vaka sınıfları ile

+4

final sadece sınıfın genişletilemeyeceği anlamına gelir, örnek oluşturma :-) ile ilgisi yoktur. Vaka sınıfı temel olarak bir 'kibrit davası' bloğunda karşılaştırılabilecek bir sınıftır. – aishwarya

cevap

6

: Sen new durum sınıfları örneğini

class Foo(val value: Int) 
object Foo { def apply(value: Int) = new Foo(value) } 

val x = new Foo(42) // 
val y = Foo(42)  // both work the same 

eğer istemek. Teorik olarak biraz daha hızlı olabilir, çünkü eşlik eden nesnenin apply yönteminden geçmek zorunda kalmaz, ancak hızlı bir kıyaslama denedim ve performansta kesinlikle hiçbir fark görmedim, bu yüzden derleyici tarafından optimize edildiğini ya da yalnızca küçük bir boyutta olduğunu gerçek inşaat ile karşılaştırıldığında fark.

Bu nedenle, verdiğiniz örnekte new'un herhangi bir önemi olduğunu düşünmüyorum ve aynı zamanda dışarıda bırakılmış olabilir.

3

Doğru; new zorunlu değildir. Onlar sadece yanı böyle örnek yöntemi List#:: tanımlanmış olabilir:

def ::[U >: T](x: U): List[U] = scala.::(x, this) 

(Sahip olduğumuz Not: scala paket nesnesinde tanımlanan

type :: = collection.immutable.:: 
val :: = collection.immutable.:: 

; ilk neden new scala.::(x, this) çalışır ve ikincisi, benim scala.::(x, this) çalışmamın nedenidir.)

The form the library uses yapıcıyı sizinki gibi doğrudan çağırır. Alternatif, :: kasa sınıfı için oluşturulan sentetik tamamlayıcı nesnesinin apply yöntemini çağırır, bu da yalnızca yapıcıyı çağırır. Belki de kurucuyu çağırmak daha açık mı, yoksa daha verimli mi? (

def ::[U >: T](x: U) = ::(x, this) 

bazı tuhaf için yanlış olabilir: (. Derleyici apply çağrısını satır içi etmezse beri Verimlilik kazanımları olsa da, hiçbir şey yakın olmalıdır, JVM olacak) ben en kompakt formu varsayalım yani, imkansız) bir tür tekrarlayıcı çağrı ve herhangi bir oranda :: ve :: adı verilen List metodu arasındaki ayrımı bulanıklaştırır, Prof. Odersky okuyucu algılamayı en üst düzeye çıkarmak için ayrı tutmak için ağrıları alır.

Bu yardımcı olur umarım.