Eğer benim gibi olursanız, zaman zaman Scala koleksiyonları veya dizileri için gelişmiş yöntemler yazmak istersiniz, ancak koleksiyon türünün yanı sıra sadece Seq [T] 'ye değil, öğe tipini de bağlamak istersiniz.Koleksiyon türünü ve öğe türünü bağlayan genel Scala geliştirme yöntemlerini nasıl yazabilirsiniz?
Q
Koleksiyon türünü ve öğe türünü bağlayan genel Scala geliştirme yöntemlerini nasıl yazabilirsiniz?
6
A
cevap
7
Bunu yapmanın bir yolu olduğunu ve bu gibi çalışır: geliştirilmiş yöntemler eleman tipi hem farkında yukarıdaki tip imza deseni kullanarak
object enhance {
import scala.language.higherKinds
import scala.language.implicitConversions
import scala.collection.SeqLike
import scala.collection.generic.CanBuildFrom
implicit class Enhance[T, S[E] <: SeqLike[E, S[E]]](seq: S[T]) {
def first3(implicit cbf: CanBuildFrom[S[T], T, S[T]]) = seq.take(3)
def foo = seq.iterator
def goo(implicit cbf: CanBuildFrom[Nothing, T, S[T]]) = foo.take(3).to[S]
def moo[U](f: T => U)(implicit cbf: CanBuildFrom[S[T], U, S[U]]) = seq.map(f)
}
}
T
(örn Int
veya String
) ve, daha iyi türden dizi tipi S
(ör. List
veya Vector
) ve böylece tam olarak çağrıldığı dizi tipine dönebilir. Birçok sıralı yöntem, Enhance
yöntemine örtük parametreler olarak eklenen, yukarıdaki örneklerde ihtiyaç duyulan CanBuildFrom
implicits gerektirebilir. Ayrıca
scala> import enhance._
import enhance._
scala> (1 to 10).toList.first3
res0: List[Int] = List(1, 2, 3)
scala> (1 to 10).toVector.first3
res1: Vector[Int] = Vector(1, 2, 3)
scala> (1 to 10).toList.goo
res2: List[Int] = List(1, 2, 3)
scala> (1 to 10).toVector.goo
res3: Vector[Int] = Vector(1, 2, 3)
scala> (1 to 10).toList.moo(_.toDouble)
res4: List[Double] = List(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0)
scala> (1 to 10).toVector.moo(_.toDouble)
res5: Vector[Double] = Vector(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0)
Eğer gizli sınıf [T, S, [E]
istenen yüksek kinded toplama geri tiplerini gösteren bir numune çalıştırmak [E]]] (seq: S [T]) {'ve daha sonra ihtiyacınız olmayacak ' –
' map 'veya' CanBuildFrom 'yöntemini yeni bir yöntemle kullanan başka bir yöntem kullanırsanız işe yaramaz. uygulamalar. Sonuç sadece 'Seq' olarak çıkar. İlgili bir "CanBuildFrom" öğesini "Enhance" sınıfına veya yönteme iletmeniz gerekir. – Kolmar
Teşekkür @ НиколайМитропольский ve Kolmar, bu değişikliklerin her ikisi de çok yararlı! Onları eylem halinde göstermek için orijinal cevabımı yeniden düzenledim. – eje