SORU
4 Mart 2011, Cuma


Nasıl Scala koleksiyonları göster işlemi doğru koleksiyon türü dönebilirler?

Not: Bu sorular, sorulan, net bir cevap verebilirim kendim olarak bu sorunu gibi görünüyor gelmek oldukça sık ve giymek istiyorum bir konumu olabilir (umarım) kolay bir şekilde, üzerinden bir arama yapın

answer here benim . bir yorumda belirtildiği


Örneğin:

"abcde" map {_.toUpperCase} //returns a String
"abcde" map {_.toInt} // returns an IndexedSeq[Int]
BitSet(1,2,3,4) map {2*} // returns a BitSet
BitSet(1,2,3,4) map {_.toString} // returns a Set[String]

Bu scaladoc bakarak, bunların hepsi map operasyon TraversableLike, miras nasıl kullandığını her zaman en özel geçerli koleksiyon dönmek mümkün oluyor? Hatta örtülü bir dönüştürme) map sağlayan String,.

CEVAP
5 Mart 2011, CUMARTESİ


Scala koleksiyonları zeki şeyler

Koleksiyon kütüphanenin iç Scala topraklarda daha gelişmiş konularından biridir. Yüksek kinded türleri, çıkarım, varyans, implicits ve CanBuildFrom mekanizma - inanılmaz derecede genel, kullanımı kolay ve kullanıcı bakan açısından güçlü yapmak için tüm içerir. Bakış açısı; bir API tasarımcı bu anlayış bir acemi tarafından alınacak açık yürekli bir görev değildir.

Öte yandan, gerçekten bu derinlikte koleksiyonları ile çalışmak gerekir, bu çok nadir görülür.

Haydi başlayalım o zaman...

Serbest bırakılması ile Scala 2.8, koleksiyon kütüphane tamamen yeniden yazılmış kaldırmak çoğaltılması, pek çok yöntem etkilediği için sadece tek bir yerde, böylece sürekli bakım ve ayrıca yeni toplama yöntemleri çok daha kolay olurdu, ama aynı zamanda yapar hiyerarşiyi anlamak zor.

Örneğin List, (sırayla) bu devralır

  • LinearSeqOptimised
  • GenericTraversableTemplate
  • LinearSeq
  • Seq
  • SeqLike
  • Iterable
  • IterableLike
  • Traversable
  • TraversableLike
  • TraversableOnce

Bir avuç oldukça! Neden hiyerarşi derin bu? Görmezden XxxLike özellikleri kısaca, her katman grubu ekler biraz işlevselliği, ya da daha optimize edilmiş versiyonu miras işlevselliği (örneğin, çekici bir öğe tarafından indeks Traversable gerektirir bir arada drop head operasyon, fena halde verimsiz bir dizin oluşturulmuş sıralı). Mümkünse, tüm işlevselliği mümkün olduğu hiyerarşi kadar yukarı itilir, kullanabilirsiniz sınıflarının sayısının artırılması ve çoğaltılması kaldırılıyor.

map sadece bir örnek. Bu yöntem uygulanır TraversableLike (Ama XxxLike özellikleri sadece gerçekten var kütüphane tasarımcılar, bu yüzden genellikle kabul edilir bir yöntem Traversable en niyet ve amaçlar - geleceğim için bu kısmı kısa bir süre), ve yaygın olarak miras kaldı. Olası bazı alt sınıfta optimize edilmiş bir sürümünü tanımlamak için, ama hala aynı imza uyması gerekir. map aşağıdaki kullanımları da söz konusu sözü gibi) göz önünde bulundurun:

"abcde" map {_.toUpperCase} //returns a String
"abcde" map {_.toInt} // returns an IndexedSeq[Int]
BitSet(1,2,3,4) map {2*} // returns a BitSet
BitSet(1,2,3,4) map {_.toString} // returns a Set[String]

Her durumda, çıktı, mümkün olan her yerde giriş olarak aynı türden. Mümkün değil, giriş türü superclasses bir bulununcaya kadar kontrol ediliryokgeçerli bir dönüş türü sunuyoruz. Bu doğru almak bir sürü iş, özellikle String bile bir koleksiyon olmadığını düşündüğünüz zaman, sadece tek bir örtük olarak dönüştürülebilir şey aldı.

Nasıl yapılır?

Bulmacanın bir yarım XxxLike özellikleri (benyaptıderdim olsun onlara...), kimin ana fonksiyon için Repr yazın param (kısaca "Temsil") böylece bil, gerçek alt sınıf aslında ameliyat olmak. Örneğin TraversableLike Traversable, de Repr yazın param soyutlanmış sona erdi. Bu param kullanılan ikinci yarısı bulmaca; CanBuildFrom türü sınıf yakalayan kaynak toplama türü, hedef öğe türü ve hedef koleksiyon türü için kullanılan toplama dönüşüm işlemleri.

Daha kolay bir örnek ile bunu açıklamak!

BitSet böyle CanBuildFrom örtülü bir örneğini tanımlar:

implicit def canBuildFrom: CanBuildFrom[BitSet, Int, BitSet] = bitsetCanBuildFrom

BitSet(1,2,3,4) map {2*}, derlemek, derleyici CanBuildFrom[BitSet, Int, T] kesin bir arama çalışacaktır

Bu akıllı bir parçasıdır... ilk iki tür parametreleri ile eşleşen tek bir kapsamda örtülü Var. İlk parametre XxxLike özelliği tarafından esir olarak Repr, ikincisi de geçerli toplama özelliği (örneğin Traversable) tarafından esir olarak element türüdür. map ameliyattan sonra da örtülü olarak bulunan bir tür, bu tür T üçüncü tip CanBuildFrom örnek parametre dayalı olarak algılanır ile parametrik. Bu durumda BitSet.

Yani CanBuildFrom ilk iki tür parametreleri girişi, örtülü arama için kullanılacak ve üçüncü parametre, kesmesi için kullanılan bir çıkış.

BitSet bu nedenle iki tür maçlar BitSet Int, arama başarısız olur ve olayla dönüş tipi CanBuildFrom de BitSet olacak.

BitSet(1,2,3,4) map {_.toString}, derlemek, derleyici CanBuildFrom[BitSet, String, T] kesin bir arama çalışacaktır. Bu derleyici gelecek Bu örtülü içerir- Set - onun üst deneyecek kadar BitSet içinde örtülü için başarısız olacak

implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Set[A]] = setCanBuildFrom[A]

Hangi Coll bir tip olduğu için maçları BitSet Set türetir BitSet olmak başlatıldığını bunun diğer adı. A maç olacak bir şey gibi canBuildFrom parametrik ile tür A, bu durumda bu algılanır String... Böylece verimli bir dönüş türü Set[String].

Çok doğru uygulayan bir koleksiyon türü, sadece sağlamak için ihtiyaç bir doğru örtülü türü CanBuildFrom ama aynı zamanda ihtiyacınız sağlamak için beton türü olan bu koleksiyon olarak sağlanan Repr param için doğru ebeveyn özellikleri (örneğin, bu MapLike davanın sınıflara Map).

String map sağladığı için biraz daha karmaşık bir örtük dönüştürme. Örtülü dönüşüm Repr yazın param olmak sonuçtaTraversableLike[Char,String] - String türetilen StringLike[String], alt sınıflar StringOps.

Derleyici Char s String öğeleri eşleme, sonra da dönüş türü de bir dize olması gerektiğini bilir, bu nedenle de kapsam CanBuildFrom[String,Char,String]bir şey var. Bu noktadan itibaren, aynı düzenek kullanılır.

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Blendtec

    Blendtec

    30 EKİM 2006
  • magnum33563

    magnum33563

    8 NİSAN 2011
  • Top Gear

    Top Gear

    27 Mart 2006