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
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ı?
CanBuildFrom
gelelim'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. map
bakarak'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
, List
soru 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.
Scala: en İyi komut satırı parametrele...
Farklı Scala Aktör Uygulamaları Genel ...
Hoogle eşdeğer Scala?...
Scala, açıklama değer adı vs çağrısıyl...
Scala: [List] Geleceği hiçe sayılarak ...