2013-05-29 72 views
8

正如這個問題的標題所示:我的問題更多地是關於形式(慣用約定)而不是函數。將簡潔地:Idiomatic Sc​​ala:<Collection> Like和<Collection>類型之間的語義區別?

是什麼MyCollectionLikeMyCollection之間的語義差別?

作爲例子:是什麼StringLikeString和或MapLikeMap之間的差異。仔細查看Scala API文檔,我可以看出XLike通常是X的超級類型。但是,除此之外,我不清楚這些抽象層之間的語義差異。

實際上,如果我正在創建一個新的類/特徵,那麼當我爲這個類選擇名稱時,理解這個區別將會很有幫助。

我的具體問題,在這又拿出如下:

我想創建性狀:SurjectiveMap[K, T]可以混在任何Map[K, Set[T]]MapLike[K, SetLike[T]]。鑑於我不知道*Like*之間的語義差異,我不確定該去哪。

回答

3

同樣的差作爲的IFoo與富,酒吧和BarImpl之間(不包含實現的事實,TraversableLike是超級性狀):

斯卡拉集合庫避免了重複代碼,並達到 通過使用通用構建器和遍歷所謂的實現特徵中的集合的 來實現「相同結果類型」原則。這些特徵是用Like後綴命名的 ;比如IndexedSeqLike是IndexedSeq的 實現特徵,同樣TraversableLike也是 Traversable的實現特徵。集合類如 Traversable或IndexedSeq從這些特徵繼承其所有具體方法 實現。

Scala collections architecture

1

我想到用Like特質讓你細化回報(表示)類型。這涉及更多的工作。比較:

import collection.generic.CanBuildFrom 

object FooMap { 
    type Coll = FooMap[_, _] 
    implicit def canBuildFrom[A, B]: CanBuildFrom[Coll, (A, B), FooMap[A, B]] = ??? 
} 
trait FooMap[A, +B] extends Map[A, B] { 
    def foo = 33 
} 

def test(f: FooMap[Any, Any]) { 
    f.map(identity).foo // nope, we ended up with a regular `Map` 
} 

object FooMap extends collection.generic.ImmutableMapFactory[FooMap] { 
    override type Coll = FooMap[_, _] 
    implicit def canBuildFrom[A, B]: CanBuildFrom[Coll, (A, B), FooMap[A, B]] = ??? 
    def empty[A, B]: FooMap[A, B] = ??? 
} 
trait FooMap[A, +B] extends Map[A, B] 
    with collection.immutable.MapLike[A, B, FooMap[A, B]] { 

    def foo = 33 
    override def empty: FooMap[A, B] = FooMap.empty[A, B] 
} 

def test(f: FooMap[Any, Any]) { 
    f.map(identity).foo // yes 
} 

MapLike特質必須Map特質後混合在正確的返回類型踢


你仍然沒有得到。似乎免費的一切,例如您將需要覆蓋更多方法:

override def +[B1 >: B](kv: (A, B1)): FooMap[A, B1] // etc. 
相關問題