2014-09-11 37 views
0

我必須實現某些功能的類(提供L-系統烏龜圖形界面,但是這裏並不重要):轉發參數列表功能

abstract class LSystem 
{ 
    def BranchBegin() 
    def BranchEnd() 
    def Rotate(axis:Vector3f, angle:Float) 
    def MoveForward(dist:Float) 
    def DrawForward(size:Float, color:ColorRGBA) 
    def DrawSphere(size:Float, color:ColorRGBA) 
} 

我有AA特質prodiving一些助手:

trait LSystemShortcuts { 
    def <()(implicit lsys:LSystem)= lsys.BranchBegin() 
    def S(size:Float, color:ColorRGBA)(implicit lsys:LSystem)= lsys.DrawSphere(size,color) 
    def >()(implicit lsys:LSystem)= lsys.BranchEnd() 
} 

終於有一個單獨的L系統,看起來像這樣:

class RoundTree(implicit lsys:LSystem) extends LSystemShortcuts { 
    // TODO: move to LSystemShortcuts 
    def F = lsys.DrawForward _ 
    def R = lsys.Rotate _ 
    def M = lsys.MoveForward _ 

    val degree = PI.toFloat/180 
    val colorCrown = ColorRGBA.SRGB(0.1f,0.4f,0.05f, 1) 
    val colorTrunk = ColorRGBA.SRGB(0.1f,0.1f,0.05f,1) 

    def C(size:Float, iterations:Int) = { 
    if (iterations>0) { 

     F(size*0.5f,colorTrunk) 

     < 
     C(size*0.5f,iterations-1) 
     > 

     < 
     R(Vector3f(0,0,1),+75*degree) 
     C(size*0.3f,iterations-1) 
     > 

     // some more rendering code here 

    } 
    else 
    { 
     F(size,colorTrunk) 
     M(size*0.6f) 
     S(size*0.7f,colorCrown) 
    } 
    } 
} 

請注意,當前的快捷方式F,RM直接在RoundTree類中定義。我想將它移至LSystemShortcuts特徵,但我想避免重複參數列表(目前通過使用部分應用的函數完成),就像它爲S快捷方式完成一樣。使用LSystemShortcuts作爲基類會很容易,但我不喜歡這樣的設計,特徵似乎更合適。

定義函數時是否有某種方法來轉發參數列表?沿路線的東西:

def R(_)(implicit lsys:LSystem) = lsys.Rotate _ 

或許一些其他的設計,具有LSystemShortcuts作爲成員,而不是一個特點,這將使我才達到的?

回答

1

嗯,我可以猜測一種骯髒的解決方法。您可以使用受保護的會員更改您的trait的定義。

trait A { 
    protected var i: Int = 0 // has to be initialized, won't compile otherwise 
    def print = println(i) 
} 

之後,你可以按如下方式使用該成員:

class B extends A { 
    i = 10 
    print 
} 

new B()呼叫將打印10到控制檯。
我希望這可以按照預期回答你的問題。否則,我會很樂意嘗試解決另一個問題。

+0

我認爲這可以修改成完美的東西:我可以有(未初始化,抽象)val lsys:特徵中的LS系統。然後RoundTree執行此操作,並且該特徵可以使用它。爲什麼Int必須被初始化?我雖然一個特質可以包含抽象值。 – Suma 2014-09-11 14:07:12

+0

在你的情況下,它可能是:在特質A def I:Int和B類val i = 10中。 – Suma 2014-09-11 14:59:56

+0

我試過了,在REPL中,它告訴我,我不能以這種方式寫它,而不初始化它第一。但如果它適合你,我不介意。 – 2014-09-12 09:45:23

0

據我所知,這是不可能的,因爲scala不像Haskell那樣支持point-free style notation

恐怕沒有辦法明確地傳遞其他參數。