将参数列表转发给函数

时间:2014-09-11 08:55:30

标签: function scala arguments

我有一个实现某些功能的类(为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)
}

我有一个特质刺激一些帮助者:

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)
    }
  }
}

请注意,目前的快捷方式FRM直接在RoundTree类中定义。我想将它移到LSystemShortcuts特征,但我想避免重复参数列表(目前这是通过使用部分应用函数完成的),就像它是为S快捷方式完成的那样。使用LSystemShortcuts作为基类很容易,但我不喜欢这样的设计,特性似乎更合适。

在定义函数时是否有某种方法可以转发参数列表?沿着以下几点:

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

或许还有其他一些设计,LSystemShortcuts作为成员而不是特质,这会让我实现这个目标?

2 个答案:

答案 0 :(得分: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打印到控制台。 我希望这能按照预期回答你的问题。否则,我很乐意尝试找出另一种解决方案。

答案 1 :(得分:0)

据我所知,这是不可能的,因为scala不像Haskell那样支持point-free style notation

我担心除了显式之外,没有办法传递参数。