2016-02-08 38 views
0

我想添加約束到一個特質的類型字段作爲額外的特徵混入,但似乎無法找到一種方式來表達任何幫助讚賞:是否有可能「混入:附加類型約束

trait Events { def be() = println("B") } 
trait Create { self : Events => def create() = println("C") } 
trait Update { self : Events => def update() = println("U") } 
trait Delete { self : Events => def delete() = println("D") } 

trait EventHandler { 
    type MyEvents <: Events 
    val myEvents : MyEvents 
} 

trait Creation { 
    self: EventHandler => 
    override type MyEvents <: Create 
} 

def h(events: EventHandler with Creation) : Unit = { 
    events.myEvents.be() // <== wont' compile 
    events.myEvents.create() 
} 

編譯器說:

<console>:12: error: value be is not a member of events.MyEvents 
+0

見下面我修改後的答案,這是我的一個學習項目,以及一個例子 - 我會盡量遠離這麼多自種 – LaloInDublin

回答

0

好一些我以前的評論是錯誤的,我不知道自己打字隱藏你正在使用的接口,因此是不一樣的「extend」。下面是一個更好的解釋鏈接:

http://www.andrewrollins.com/2014/08/07/scala-cake-pattern-self-type-annotations-vs-inheritance/

在代碼中創建的邏輯衝突太多,所以我不會在這裏嘗試重寫它。你的代碼中的這些衝突歸結爲這個 - 你的一些邏輯打開了特性API,然後你的一些自我類型立即隱藏它們。下面是幫助我瞭解爲什麼

trait A { 
    def x:Int 
} 
    trait B { self:A => 

    } 

    def workWithB(b:B): Unit ={ 
    b.x //wont' compile, is forced hidden. 
    } 
+0

感謝遷移的想法,但沒有按不是很有效 - 覆蓋顯然完全覆蓋了定義,所以myEvents不再是「創建事件」,而是「創建」(大概在創建範圍內) 缺少的是某種方式來表達「<它之前是什麼我與Create創建混合「。換句話說像「super.MyEvents與創建」 – jmcnulty

+0

@ user3324500也許我不明白,因爲創建被定義爲「self:Events =>」,它已經(根據定義)「事件與創造」。沒有理由再次聲明該語法。 – LaloInDublin

+0

有趣的是,我一直認爲「自我:事件=>」不同於「創建擴展事件」 - 後者是「創建是事件的子類型」的事實,而前者不影響類型的創建,而是約束它可以成爲其一部分的實例的類型。 PS我也嘗試了「覆蓋類型MyEvents = self.type.MyEvents與創建」具有相同的結果 – jmcnulty

相關問題