2014-09-11 66 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

恐怕没有办法明确地传递其他参数。