2014-09-11 5 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) 
} 

У меня есть аа черта 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, R и M определены непосредственно в классе 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: LSystem в черте. Тогда RoundTree реализует это, и черта может его использовать. Почему Int должен быть инициализирован? Я, хотя черта может содержать значения абзаца. – Suma

+0

В вашем случае это может быть: в признаке A def i: Int и в классе B val i = 10. – Suma

+0

Я пробовал, что в REPL и мне сказали, что я не могу записать его таким образом, не инициализируя его первый. Но если это сработает для вас, я не против. –

0

Насколько мне известно, это невозможно, поскольку scala не поддерживает point-free style notation как Haskell.

Боюсь, что аргументы, отличные от явно, отсутствуют.

Смежные вопросы