Scala'da, mevcut veya yeni tipleri güçlendirmek için en az iki yöntem kullanabiliriz. Diyelim ki bir şeyin bir Int
. Aşağıdaki özelliği tanımlayabiliriz.
Örtük dönüştürme
trait Quantifiable{ def quantify: Int }
Ve sonra ör. Dizeler ve Listeler'i ölçmek için örtük dönüştürmeleri kullanabiliriz.
implicit def string2quant(s: String) = new Quantifiable{
def quantify = s.size
}
implicit def list2quantifiable[A](l: List[A]) = new Quantifiable{
val quantify = l.size
}
Bunları içe aktardıktan sonra quantify
, dizge ve listeler üzerinde yöntemi çağırabiliriz . Ölçülebilir listenin uzunluğunu sakladığını ve böylece sonraki aramalarda listenin pahalı geçişini önlediğini unutmayın quantify
.
Tip sınıfları
Bir alternatif, Quantified[A]
bazı tiplerin A
ölçülebileceğini belirten bir "tanık" tanımlamaktır .
trait Quantified[A] { def quantify(a: A): Int }
Daha sonra bu tür sınıfın örneklerini için String
ve bir List
yerde sağlıyoruz.
implicit val stringQuantifiable = new Quantified[String] {
def quantify(s: String) = s.size
}
Ve sonra argümanlarını ölçmesi gereken bir yöntem yazarsak, şunu yazarız:
def sumQuantities[A](as: List[A])(implicit ev: Quantified[A]) =
as.map(ev.quantify).sum
Veya bağlama bağlı sözdizimini kullanarak:
def sumQuantities[A: Quantified](as: List[A]) =
as.map(implicitly[Quantified[A]].quantify).sum
Ama hangi yöntem ne zaman kullanılmalı?
Şimdi soru geliyor. Bu iki kavram arasında nasıl karar verebilirim?
Şimdiye kadar ne fark ettim.
tip sınıfları
- tür sınıfları güzel bağlam bağlantılı sözdizimine izin verir
- tür sınıflarıyla her kullanımda yeni bir sarmalayıcı nesne oluşturmuyorum
- tür sınıfının birden çok tür parametresi varsa, bağlama bağlı sözdizimi artık çalışmaz; Bir şeyleri sadece tamsayılarla değil, bazı genel tipteki değerlerle ölçmek istediğimi hayal edin
T
. Bir tür sınıfı oluşturmak isterdimQuantified[A,T]
örtük dönüştürme
- yeni bir nesne oluşturduğum için, orada değerleri önbelleğe alabilir veya daha iyi bir temsil hesaplayabilirim; ancak bundan kaçınmalı mıyım, çünkü bu birkaç kez olabilir ve açık bir dönüştürme muhtemelen yalnızca bir kez çağrılabilir?
Bir cevaptan ne bekliyorum
Her iki kavram arasındaki farkın önemli olduğu bir (veya daha fazla) kullanım durumunu sunun ve neden birini diğerine tercih ettiğimi açıklayın. Ayrıca iki kavramın özünü ve birbirleriyle ilişkilerini açıklamak, örnek olmasa bile güzel olurdu.