SORU
11 Kasım 2009, ÇARŞAMBA


Scala 2.8 ara

Scala2.8, scala.collection.package.scala bir nesne var:

def breakOut[From, T, To](implicit b : CanBuildFrom[Nothing, T, To]) =
    new CanBuildFrom[From, T, To] {
        def apply(from: From) = b.apply() ; def apply() = b.apply()
 }

Bu sonuçlar söylendi:

> import scala.collection.breakOut
> val map : Map[Int,String] = List("London", "Paris").map(x => (x.length, x))(breakOut)

map: Map[Int,String] = Map(6 -> London, 5 -> Paris)

Burada neler oluyor? Neden breakOut * deniyorbağımsız değişken olarakbenim için List?

CEVAP
11 Kasım 2009, ÇARŞAMBA


Cevap map tanımı bulunur:

def map[B, That](f : (A) => B)(implicit bf : CanBuildFrom[Repr, B, That]) : That 

İki parametre olduğunu unutmayın. İlk fonksiyon ve ikinci bir örtülü. Eğer Evren'in verirseniz, Scala en seçecektirözelbir kullanılabilir.

breakOut hakkında

, breakOut amacı nedir? Örnek soru için verilen düşünün, dizeleri bir liste, bir demet 28 ** ve sonra da Map üretmek her dize dönüştürmek. List[(Int, String)] aracı bir koleksiyon üretmek ve dönüştürmek sonra bunun en belirgin şekilde.

map Builder elde edilen koleksiyon üretmek için kullandığı düşünülürse, aracı atlamak mümkün List ve sonuçları doğrudan Map içine toplamak değil mi? Besbelli, Evet, öyle. Bunu yapmak için, ancak, map CanBuildFrom doğru geçmemiz lazım ve o breakOut tam olarak ne olduğunu.

Haydi, o zaman, breakOut tanım:

def breakOut[From, T, To](implicit b : CanBuildFrom[Nothing, T, To]) =
  new CanBuildFrom[From, T, To] {
    def apply(from: From) = b.apply() ; def apply() = b.apply()
  }

breakOut parametreli ve CanBuildFrom bir örneğini verir unutmayın. Aslında bu tür From, T To map CanBuildFrom[List[String], (Int, String), Map[Int, String]] beklediğini biliyoruz çünkü olayla edilmiştir. Bu nedenle:

From = List[String]
T = (Int, String)
To = Map[Int, String]

Sonuç olarak bu örtülü breakOut tarafından alınan kendisi inceleyelim. Tür CanBuildFrom[Nothing,T,To]. Biz zaten tüm bu türleri biliyorum, 50 ** tür örtülü ihtiyacımız olduğunu tespit edebiliriz. Ama böyle bir tanımı var mı?

CanBuildFromgelelim'nin tanımı:

trait CanBuildFrom[-From, -Elem,  To] 
extends AnyRef

CanBuildFrom ilk tür parametresi contra-varyant. Nothing alt sınıf (örneğin, her bir alt sınıf yani) çünkü, anlamına gelirherhangi birsınıf Nothing yerine kullanılabilir.

Böyle bir inşaatçı var olduğundan, Scala istenen çıkış oluşturmak için kullanabilirsiniz.

Yapanlar Hakkında

Bir sürü yöntemleri Scala'nın koleksiyonlar kütüphane oluşur alarak orijinal toplama, işleme bir şekilde (map, dönüştüren her unsuru) ve depolama sonuçlarında yeni bir koleksiyon.

Kodu yeniden en üst düzeye çıkarmak için, sonuçlar bu depolama yapılırbuilderTemelde iki operasyonları destekler: (scala.collection.mutable.Builder), eleman ekleme, ve elde edilen tahsilat dönüyor. Bu sonuç koleksiyon türü oluşturucu türüne bağlı olacaktır. Böylece, List inşaatçı List, Map inşaatçı ** 61, ve böylece bir döner bir döner. map yöntemin uygulanması gereken sonuç türü ile kendisini ilgilendiren bir durum değil: oluşturucu ilgileniyor.

Öte yandan, bu map Bu oluşturucu bir şekilde almaya ihtiyacı var demektir. Sorun Scala 2.8 Koleksiyonları tasarlarken karşılaştığı en iyi builder mümkün seçmek için nasıl. *Eğer 64*, ben yazmaya olsaydı örneğin, Map(1 -> 'a') geri almak istiyorum. Diğer taraftan, Map('a' -> 1).map(_._1) Map (Iterable döner) dönüş yok.

İfadenin bilinen türleri mümkün olan en iyi Builder üreten büyüsü CanBuildFrom bu örtülü gerçekleştirilir.

CanBuildFrom hakkında

Neler olduğunu daha iyi açıklamak için, koleksiyon eşlenen Map bir örnek yerine List vereceğim. List daha sonra tekrar geleceğim. Şimdilik, bu iki ifadeyi düşünün:

Map(1 -> "one", 2 -> "two") map Function.tupled(_ -> _.length)
Map(1 -> "one", 2 -> "two") map (_._2)

İlk döndürür* *76 ve ikinci döndürür Iterable. Uydurma bir koleksiyon döndürme büyüsü CanBuildFrom eseridir. Hadi map tanımını yeniden anlamak için düşünün.

80* *yöntemi TraversableLike devralmış. B That parametreli hale getirilmiş ve tür parametreleri A ve sınıf stratejisinin olan Repr, kullanır. Hadi, her iki tanım bir arada görmek:

86* *sınıfı olarak tanımlanır:

trait TraversableLike[ A,  Repr] 
extends HasNewBuilder[A, Repr] with AnyRef

def map[B, That](f : (A) => B)(implicit bf : CanBuildFrom[Repr, B, That]) : That 

A Repr nereden geldiğini anlamak için, hadi Map kendi tanımını göz önünde bulundurun:

trait Map[A,  B] 
extends Iterable[(A, B)] with Map[A, B] with MapLike[A, B, Map[A, B]]

TraversableLike uzanan tüm özelliklerini miras olduğu için*, A *93 Repr onlara herhangi bir miras olabilir. Son bir tercih olsa da olur. Bağlamak için o kadar değişmez tanımı aşağıdaki Map ve tüm özellikleri TraversableLike,: için

trait Map[A,  B] 
extends Iterable[(A, B)] with Map[A, B] with MapLike[A, B, Map[A, B]]

trait MapLike[A,  B,  This <: MapLike[A, B, This] with Map[A, B]] 
extends MapLike[A, B, This]

trait MapLike[A,  B,  This <: MapLike[A, B, This] with Map[A, B]] 
extends PartialFunction[A, B] with IterableLike[(A, B), This] with Subtractable[A, This]

trait IterableLike[ A,  Repr] 
extends Equals with TraversableLike[A, Repr]

trait TraversableLike[ A,  Repr] 
extends HasNewBuilder[A, Repr] with AnyRef

Geçersen tür parametreleri Map[Int, String] tüm yol aşağı zinciri bulursak, bu tür geçirilen TraversableLike ve, bu nedenle, kullanılan map,:

A = (Int,String)
Repr = Map[Int, String]

Arka örnek olacak, ilk Haritayı tür bir fonksiyonu ((Int, String)) => (Int, Int) ve ikinci harita türü bir fonksiyon alıyor ((Int, String)) => Int alıyor. Gördüğümüz gibi bir demet A türü olarak kabul ediliyor vurgulamak için çift parantez kullanıyorum.

Bu bilgi ile, hadi diğer türleri düşünün.

map Function.tupled(_ -> _.length):
B = (Int, Int)

map (_._2):
B = Int

Tipi map ** 108, ikincisine ise ilk tarafından döndürülen Iterable[String] olduğunu görebilirsiniz. mapbakarak'nin tanımı, kolay bu That değerlerini görmek için. Ama nereden geliyorlar?

Eğer söz konusu sınıfların arkadaşı nesneleri içine bakarsak, bazı örtülü bildirimleri sağlayarak görüyoruz. Nesne Map:

implicit def  canBuildFrom [A, B] : CanBuildFrom[Map, (A, B), Map[A, B]]  

Ve Map uzatılmış olan Iterable nesne:

implicit def  canBuildFrom [A] : CanBuildFrom[Iterable, A, Iterable[A]]  

Bu tanımlar CanBuildFrom parametreli fabrikaları bulunur.

Scala en özel örtülü kullanılabilir seçecektir. İlk durumda, 118* *ilk oldu. İlk maçta yaptığı gibi ikinci durumda, 119* *ikinci seçti.

Soruma geri dönelim

, Listsoru kodunu görelim'ler ve map'tanımı (tekrar) türleri olayla nasıl olduğunu görmek için:

val map : Map[Int,String] = List("London", "Paris").map(x => (x.length, x))(breakOut)

sealed abstract class List[ A] 
extends LinearSeq[A] with Product with GenericTraversableTemplate[A, List] with LinearSeqLike[A, List[A]]

trait LinearSeqLike[ A,  Repr <: LinearSeqLike[A, Repr]] 
extends SeqLike[A, Repr]

trait SeqLike[ A,  Repr] 
extends IterableLike[A, Repr]

trait IterableLike[ A,  Repr] 
extends Equals with TraversableLike[A, Repr]

trait TraversableLike[ A,  Repr] 
extends HasNewBuilder[A, Repr] with AnyRef

def map[B, That](f : (A) => B)(implicit bf : CanBuildFrom[Repr, B, That]) : That 

List("London", "Paris") tipi A ** 126 ** 127 *tanımlanmış tip yani 124**,:

A = String
Repr = List[String]

(x => (x.length, x)) type B türü (String) => (Int, String),:

B = (Int, String)

Geçen bilinmeyen tip, That* *134, sonucu türüdür ve zaten de bu var:

val map : Map[Int,String] =

Yani

That = Map[Int, String]

breakOut, mutlaka, bir tür iade veya CanBuildFrom[List[String], (Int, String), Map[Int, String]] alt gerektiği anlamına gelir.

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Hudson Music

    Hudson Music

    13 Mart 2007
  • kimberly p

    kimberly p

    23 Ocak 2010
  • Sean Murphy

    Sean Murphy

    4 ŞUBAT 2009